Coverage Report

Created: 2025-08-28 06:29

/src/frr/ospfd/ospf_main.c
Line
Count
Source (jump to first uncovered line)
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 * OSPFd main routine.
4
 *   Copyright (C) 1998, 99 Kunihiro Ishiguro, Toshiaki Takada
5
 */
6
7
#include <zebra.h>
8
9
#include <lib/version.h>
10
#include "bfd.h"
11
#include "getopt.h"
12
#include "frrevent.h"
13
#include "prefix.h"
14
#include "linklist.h"
15
#include "if.h"
16
#include "vector.h"
17
#include "vty.h"
18
#include "command.h"
19
#include "filter.h"
20
#include "plist.h"
21
#include "stream.h"
22
#include "log.h"
23
#include "memory.h"
24
#include "privs.h"
25
#include "sigevent.h"
26
#include "zclient.h"
27
#include "vrf.h"
28
#include "libfrr.h"
29
#include "routemap.h"
30
31
#ifdef FUZZING
32
#include "sockopt.h"
33
#include <netinet/ip.h>
34
#endif
35
36
#include "ospfd/ospfd.h"
37
#include "ospfd/ospf_interface.h"
38
#include "ospfd/ospf_asbr.h"
39
#include "ospfd/ospf_lsa.h"
40
#include "ospfd/ospf_lsdb.h"
41
#include "ospfd/ospf_neighbor.h"
42
#include "ospfd/ospf_dump.h"
43
#include "ospfd/ospf_route.h"
44
#include "ospfd/ospf_zebra.h"
45
#include "ospfd/ospf_vty.h"
46
#include "ospfd/ospf_bfd.h"
47
#include "ospfd/ospf_gr.h"
48
#include "ospfd/ospf_errors.h"
49
#include "ospfd/ospf_ldp_sync.h"
50
#include "ospfd/ospf_routemap_nb.h"
51
52
/* ospfd privileges */
53
zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND, ZCAP_NET_ADMIN,
54
          ZCAP_SYS_ADMIN};
55
56
struct zebra_privs_t ospfd_privs = {
57
#if defined(FRR_USER) && defined(FRR_GROUP)
58
  .user = FRR_USER,
59
  .group = FRR_GROUP,
60
#endif
61
#if defined(VTY_GROUP)
62
  .vty_group = VTY_GROUP,
63
#endif
64
  .caps_p = _caps_p,
65
  .cap_num_p = array_size(_caps_p),
66
  .cap_num_i = 0};
67
68
/* OSPFd options. */
69
const struct option longopts[] = {
70
  {"instance", required_argument, NULL, 'n'},
71
  {"apiserver", no_argument, NULL, 'a'},
72
  {0}
73
};
74
75
/* OSPFd program name */
76
77
/* Master of threads. */
78
struct event_loop *master;
79
80
#ifdef SUPPORT_OSPF_API
81
extern int ospf_apiserver_enable;
82
#endif /* SUPPORT_OSPF_API */
83
84
/* SIGHUP handler. */
85
static void sighup(void)
86
0
{
87
0
  zlog_info("SIGHUP received");
88
0
}
89
90
/* SIGINT / SIGTERM handler. */
91
static void sigint(void)
92
0
{
93
0
  zlog_notice("Terminating on signal");
94
0
  bfd_protocol_integration_set_shutdown(true);
95
0
  ospf_terminate();
96
0
  exit(0);
97
0
}
98
99
/* SIGUSR1 handler. */
100
static void sigusr1(void)
101
0
{
102
0
  zlog_rotate();
103
0
}
104
105
struct frr_signal_t ospf_signals[] = {
106
  {
107
    .signal = SIGHUP,
108
    .handler = &sighup,
109
  },
110
  {
111
    .signal = SIGUSR1,
112
    .handler = &sigusr1,
113
  },
114
  {
115
    .signal = SIGINT,
116
    .handler = &sigint,
117
  },
118
  {
119
    .signal = SIGTERM,
120
    .handler = &sigint,
121
  },
122
};
123
124
static const struct frr_yang_module_info *const ospfd_yang_modules[] = {
125
  &frr_filter_info,
126
  &frr_interface_info,
127
  &frr_route_map_info,
128
  &frr_vrf_info,
129
  &frr_ospf_route_map_info,
130
};
131
132
FRR_DAEMON_INFO(ospfd, OSPF, .vty_port = OSPF_VTY_PORT,
133
134
    .proghelp = "Implementation of the OSPFv2 routing protocol.",
135
136
    .signals = ospf_signals, .n_signals = array_size(ospf_signals),
137
138
    .privs = &ospfd_privs, .yang_modules = ospfd_yang_modules,
139
    .n_yang_modules = array_size(ospfd_yang_modules),
140
);
141
142
#ifdef FUZZING
143
144
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
145
146
static bool FuzzingInit(void)
147
1
{
148
1
  unsigned short instance = 0;
149
1
  bool created = false;
150
151
1
  const char *name[] = { "ospfd" };
152
153
1
  frr_preinit(&ospfd_di, 1, (char **) &name);
154
155
156
  /* INIT */
157
1
  ospf_master_init(frr_init_fast());
158
1
  ospf_debug_init();
159
1
  ospf_vrf_init();
160
1
  access_list_init();
161
1
  prefix_list_init();
162
1
  ospf_if_init();
163
1
  ospf_zebra_init(master, instance);
164
1
  ospf_bfd_init(master);
165
1
  ospf_route_map_init();
166
1
  ospf_opaque_init();
167
1
  ospf_error_init();
168
169
1
  return true;
170
1
}
171
172
static struct ospf *FuzzingCreateOspf(void)
173
1
{
174
1
  struct prefix p;
175
1
  struct interface *ifp = if_get_by_name("fuzziface", 0, "default");
176
1
  struct vrf *vrf = vrf_get(VRF_DEFAULT, VRF_DEFAULT_NAME);
177
1
  ifp->mtu = 68;
178
1
  str2prefix("11.0.2.0/24", &p);
179
180
1
  bool created;
181
1
  struct ospf *o = ospf_get(0, VRF_DEFAULT_NAME, &created);
182
1
  o->fd = 69;
183
184
1
  struct in_addr in;
185
1
  inet_pton(AF_INET, "0.0.0.0", &in);
186
1
  struct ospf_area *a = ospf_area_new(o, in);
187
188
1
  struct connected *c = connected_add_by_prefix(ifp, &p, NULL);
189
1
  add_ospf_interface(c, a);
190
191
1
  struct ospf_interface *oi = listhead(a->oiflist)->data;
192
1
  oi->state = 7; // ISM_DR
193
194
1
  o->fuzzing_packet_ifp = ifp;
195
196
1
  return o;
197
1
}
198
199
static struct ospf *FuzzingOspf;
200
static bool FuzzingInitialized;
201
202
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
203
3.36k
{
204
3.36k
  if (!FuzzingInitialized) {
205
1
    FuzzingInit();
206
1
    FuzzingInitialized = true;
207
1
    FuzzingOspf = FuzzingCreateOspf();
208
1
  }
209
210
3.36k
  struct ospf *o;
211
212
3.36k
#ifdef FUZZING_LIBFUZZER
213
3.36k
  o = FuzzingOspf;
214
#else
215
  o = FuzzingOspf;
216
#endif
217
218
  /* Simulate the read process done by ospf_recv_packet */
219
3.36k
  stream_free(o->ibuf);
220
3.36k
  o->ibuf = stream_new(MAX(1, size));
221
222
3.36k
  stream_put(o->ibuf, data, size);
223
3.36k
  {
224
3.36k
    struct ip *iph;
225
3.36k
    unsigned short ip_len = 0;
226
227
3.36k
    if (size < sizeof(struct ip))
228
11
      goto done;
229
230
3.35k
    iph = (struct ip *)STREAM_DATA(o->ibuf);
231
3.35k
    sockopt_iphdrincl_swab_systoh(iph);
232
3.35k
    ip_len = iph->ip_len;
233
234
    // skipping platform #ifdefs as I test on linux right now
235
    // skipping ifindex lookup as it will fail anyway
236
237
3.35k
    if (size != ip_len)
238
71
      goto done;
239
3.35k
  }
240
241
3.28k
  ospf_read_helper(o);
242
243
3.36k
done:
244
3.36k
  return 0;
245
3.28k
}
246
#endif
247
248
#ifndef FUZZING_LIBFUZZER
249
/* OSPFd main routine. */
250
int main(int argc, char **argv)
251
{
252
#ifdef FUZZING
253
254
  FuzzingInitialized = FuzzingInit();
255
  FuzzingOspf = FuzzingCreateOspf();
256
257
#ifdef __AFL_HAVE_MANUAL_CONTROL
258
  __AFL_INIT();
259
#endif
260
  uint8_t *input = NULL;
261
  int r = frrfuzz_read_input(&input);
262
263
  if (r < 0 || !input)
264
    goto done;
265
266
  LLVMFuzzerTestOneInput(input, r);
267
268
  free(input);
269
done:
270
  return 0;
271
#endif
272
273
#ifdef SUPPORT_OSPF_API
274
  /* OSPF apiserver is disabled by default. */
275
  ospf_apiserver_enable = 0;
276
#endif /* SUPPORT_OSPF_API */
277
278
  frr_preinit(&ospfd_di, argc, argv);
279
  frr_opt_add("n:a", longopts,
280
        "  -n, --instance     Set the instance id\n"
281
        "  -a, --apiserver    Enable OSPF apiserver\n");
282
283
  while (1) {
284
    int opt;
285
286
    opt = frr_getopt(argc, argv, NULL);
287
288
    if (opt == EOF)
289
      break;
290
291
    switch (opt) {
292
    case 'n':
293
      ospfd_di.instance = ospf_instance = atoi(optarg);
294
      if (ospf_instance < 1)
295
        exit(0);
296
      break;
297
    case 0:
298
      break;
299
#ifdef SUPPORT_OSPF_API
300
    case 'a':
301
      ospf_apiserver_enable = 1;
302
      break;
303
#endif /* SUPPORT_OSPF_API */
304
    default:
305
      frr_help_exit(1);
306
    }
307
  }
308
309
  /* Invoked by a priviledged user? -- endo. */
310
  if (geteuid() != 0) {
311
    errno = EPERM;
312
    perror(ospfd_di.progname);
313
    exit(1);
314
  }
315
316
  /* OSPF master init. */
317
  ospf_master_init(frr_init());
318
319
  /* Initializations. */
320
  master = om->master;
321
322
  /* Library inits. */
323
  ospf_debug_init();
324
  ospf_vrf_init();
325
326
  access_list_init();
327
  prefix_list_init();
328
329
  /* OSPFd inits. */
330
  ospf_if_init();
331
  ospf_zebra_init(master, ospf_instance);
332
333
  /* OSPF vty inits. */
334
  ospf_vty_init();
335
  ospf_vty_show_init();
336
  ospf_vty_clear_init();
337
338
  /* OSPF BFD init */
339
  ospf_bfd_init(master);
340
341
  /* OSPF LDP IGP Sync init */
342
  ospf_ldp_sync_init();
343
344
  ospf_route_map_init();
345
  ospf_opaque_init();
346
  ospf_gr_init();
347
  ospf_gr_helper_init();
348
349
  /* OSPF errors init */
350
  ospf_error_init();
351
352
  frr_config_fork();
353
  frr_run(master);
354
355
  /* Not reached. */
356
  return 0;
357
}
358
#endif