From: Vasu Dasari <vdasari@gmail.com>
[mpls-ldp-portable.git] / quagga-mpls.diff
blobccca8544480018171ff4e6dabead9ff783c4d430
1 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/bgpd/bgp_nexthop.c quagga-mpls/bgpd/bgp_nexthop.c
2 --- quagga/bgpd/bgp_nexthop.c 2007-05-04 13:50:57.000000000 -0500
3 +++ quagga-mpls/bgpd/bgp_nexthop.c 2008-02-19 22:55:28.000000000 -0600
4 @@ -118,33 +118,31 @@
5 if (next1->type != next2->type)
6 return 0;
8 - switch (next1->type)
9 + if (CHECK_FLAG (next1->type, ZEBRA_NEXTHOP_IPV4))
11 - case ZEBRA_NEXTHOP_IPV4:
12 if (! IPV4_ADDR_SAME (&next1->gate.ipv4, &next2->gate.ipv4))
13 return 0;
14 - break;
15 - case ZEBRA_NEXTHOP_IFINDEX:
16 - case ZEBRA_NEXTHOP_IFNAME:
17 - if (next1->ifindex != next2->ifindex)
18 - return 0;
19 - break;
20 + }
21 #ifdef HAVE_IPV6
22 - case ZEBRA_NEXTHOP_IPV6:
23 - if (! IPV6_ADDR_SAME (&next1->gate.ipv6, &next2->gate.ipv6))
24 - return 0;
25 - break;
26 - case ZEBRA_NEXTHOP_IPV6_IFINDEX:
27 - case ZEBRA_NEXTHOP_IPV6_IFNAME:
28 - if (! IPV6_ADDR_SAME (&next1->gate.ipv6, &next2->gate.ipv6))
29 + else if (CHECK_FLAG (next1->type, ZEBRA_NEXTHOP_IPV6))
30 + {
31 + if (!IPV6_ADDR_SAME (&next1->gate.ipv6, &next2->gate.ipv6))
32 return 0;
33 + }
34 +#endif /* HAVE_IPV6 */
36 + if (CHECK_FLAG (next1->type, ZEBRA_NEXTHOP_IFINDEX))
37 + {
38 if (next1->ifindex != next2->ifindex)
39 return 0;
40 - break;
41 -#endif /* HAVE_IPV6 */
42 - default:
43 - /* do nothing */
44 - break;
45 + }
46 + else if (CHECK_FLAG (next1->type, ZEBRA_NEXTHOP_IFNAME))
47 + {
48 + if (!(next1->ifname && next2->ifname))
49 + return 0;
51 + if (strncmp(next1->ifname, next2->ifname, INTERFACE_NAMSIZ))
52 + return 0;
54 return 1;
56 @@ -714,6 +712,7 @@
57 int i;
58 u_char nexthop_num;
59 struct nexthop *nexthop;
60 + struct zapi_nexthop znh;
61 struct bgp_nexthop_cache *bnc;
63 s = zlookup->ibuf;
64 @@ -750,20 +749,27 @@
66 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
67 memset (nexthop, 0, sizeof (struct nexthop));
68 - nexthop->type = stream_getc (s);
69 - switch (nexthop->type)
70 + zapi_nexthop_read(s, &znh);
72 + nexthop->type = znh.type;
73 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV4))
74 + {
75 + nexthop->gate.ipv4.s_addr = znh.gw.ipv4.s_addr;
76 + }
77 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV6))
78 + {
79 + assert (0);
80 + }
82 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX))
83 + {
84 + nexthop->ifindex = znh.intf.index;
85 + }
86 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFNAME))
88 - case ZEBRA_NEXTHOP_IPV4:
89 - nexthop->gate.ipv4.s_addr = stream_get_ipv4 (s);
90 - break;
91 - case ZEBRA_NEXTHOP_IFINDEX:
92 - case ZEBRA_NEXTHOP_IFNAME:
93 - nexthop->ifindex = stream_getl (s);
94 - break;
95 - default:
96 - /* do nothing */
97 - break;
98 + assert (0);
101 bnc_nexthop_add (bnc, nexthop);
104 @@ -823,6 +829,7 @@
105 int i;
106 u_char nexthop_num;
107 struct nexthop *nexthop;
108 + struct zapi_nexthop znh;
109 struct bgp_nexthop_cache *bnc;
111 s = zlookup->ibuf;
112 @@ -858,27 +865,29 @@
114 for (i = 0; i < nexthop_num; i++)
116 + zapi_nexthop_read(s, &znh);
117 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
118 memset (nexthop, 0, sizeof (struct nexthop));
119 - nexthop->type = stream_getc (s);
120 - switch (nexthop->type)
121 + nexthop->type = znh.type;
123 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV4))
125 + assert (0);
127 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV6))
129 + nexthop->gate.ipv6 = znh.gw.ipv6;
132 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX))
134 + nexthop->ifindex = znh.intf.index;
136 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFNAME))
138 - case ZEBRA_NEXTHOP_IPV6:
139 - stream_get (&nexthop->gate.ipv6, s, 16);
140 - break;
141 - case ZEBRA_NEXTHOP_IPV6_IFINDEX:
142 - case ZEBRA_NEXTHOP_IPV6_IFNAME:
143 - stream_get (&nexthop->gate.ipv6, s, 16);
144 - nexthop->ifindex = stream_getl (s);
145 - break;
146 - case ZEBRA_NEXTHOP_IFINDEX:
147 - case ZEBRA_NEXTHOP_IFNAME:
148 - nexthop->ifindex = stream_getl (s);
149 - break;
150 - default:
151 - /* do nothing */
152 - break;
153 + assert (0);
156 bnc_nexthop_add (bnc, nexthop);
159 @@ -938,6 +947,8 @@
160 u_int32_t metric = 0;
161 u_char nexthop_num;
162 u_char nexthop_type;
163 + struct zapi_nexthop znh;
164 + int i;
166 /* If lookup connection is not available return valid. */
167 if (zlookup->sock < 0)
168 @@ -1007,17 +1018,22 @@
169 /* If there is nexthop then this is active route. */
170 if (nexthop_num)
172 - nexthop.s_addr = 0;
173 - nexthop_type = stream_getc (s);
174 - if (nexthop_type == ZEBRA_NEXTHOP_IPV4)
175 + for (i = 0; i < nexthop_num; i++)
177 - nexthop.s_addr = stream_get_ipv4 (s);
178 - if (igpnexthop)
179 - *igpnexthop = nexthop;
180 + zapi_nexthop_read(s, &znh);
181 + nexthop_type = znh.type;
182 + if (CHECK_FLAG (nexthop_type, ZEBRA_NEXTHOP_IPV4))
184 + nexthop.s_addr = znh.gw.ipv4.s_addr;
186 + else if (CHECK_FLAG (nexthop_type, ZEBRA_NEXTHOP_IPV6))
188 + assert (0);
191 - else
192 - *igpnexthop = nexthop;
194 + if (igpnexthop)
195 + *igpnexthop = nexthop;
196 return 1;
198 else
199 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/bgpd/bgp_route.c quagga-mpls/bgpd/bgp_route.c
200 --- quagga/bgpd/bgp_route.c 2008-09-04 20:37:35.000000000 -0500
201 +++ quagga-mpls/bgpd/bgp_route.c 2008-09-07 20:23:30.000000000 -0500
202 @@ -1893,7 +1893,10 @@
204 /* Update MPLS tag. */
205 if (safi == SAFI_MPLS_VPN)
206 - memcpy ((bgp_info_extra_get (ri))->tag, tag, 3);
208 + bgp_info_set_flag (rn, ri, BGP_INFO_MPLS);
209 + memcpy ((bgp_info_extra_get (ri))->tag, tag, 3);
212 bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
214 @@ -1923,7 +1926,10 @@
216 /* Update MPLS tag. */
217 if (safi == SAFI_MPLS_VPN)
218 - memcpy ((bgp_info_extra_get (new))->tag, tag, 3);
220 + bgp_info_set_flag (rn, new, BGP_INFO_MPLS);
221 + memcpy ((bgp_info_extra_get (new))->tag, tag, 3);
224 bgp_info_set_flag (rn, new, BGP_INFO_VALID);
226 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/bgpd/bgp_route.h quagga-mpls/bgpd/bgp_route.h
227 --- quagga/bgpd/bgp_route.h 2007-08-06 10:22:42.000000000 -0500
228 +++ quagga-mpls/bgpd/bgp_route.h 2008-02-19 22:55:29.000000000 -0600
229 @@ -76,6 +76,7 @@
230 #define BGP_INFO_STALE (1 << 8)
231 #define BGP_INFO_REMOVED (1 << 9)
232 #define BGP_INFO_COUNTED (1 << 10)
233 +#define BGP_INFO_MPLS (1 << 11)
235 /* BGP route type. This can be static, RIP, OSPF, BGP etc. */
236 u_char type;
237 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/bgpd/bgp_zebra.c quagga-mpls/bgpd/bgp_zebra.c
238 --- quagga/bgpd/bgp_zebra.c 2007-05-04 13:50:58.000000000 -0500
239 +++ quagga-mpls/bgpd/bgp_zebra.c 2008-02-22 22:38:21.000000000 -0600
240 @@ -36,6 +36,7 @@
241 #include "bgpd/bgp_nexthop.h"
242 #include "bgpd/bgp_zebra.h"
243 #include "bgpd/bgp_fsm.h"
244 +#include "bgpd/bgp_mplsvpn.h"
245 #include "bgpd/bgp_debug.h"
247 /* All information about zebra. */
248 @@ -230,73 +231,52 @@
249 static int
250 zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
252 - struct stream *s;
253 struct zapi_ipv4 api;
254 unsigned long ifindex;
255 struct in_addr nexthop;
256 struct prefix_ipv4 p;
257 + int i;
259 - s = zclient->ibuf;
260 - ifindex = 0;
261 - nexthop.s_addr = 0;
263 - /* Type, flags, message. */
264 - api.type = stream_getc (s);
265 - api.flags = stream_getc (s);
266 - api.message = stream_getc (s);
268 - /* IPv4 prefix. */
269 - memset (&p, 0, sizeof (struct prefix_ipv4));
270 - p.family = AF_INET;
271 - p.prefixlen = stream_getc (s);
272 - stream_get (&p.prefix, s, PSIZE (p.prefixlen));
274 - /* Nexthop, ifindex, distance, metric. */
275 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
277 - api.nexthop_num = stream_getc (s);
278 - nexthop.s_addr = stream_get_ipv4 (s);
280 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
282 - api.ifindex_num = stream_getc (s);
283 - ifindex = stream_getl (s);
285 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
286 - api.distance = stream_getc (s);
287 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
288 - api.metric = stream_getl (s);
289 - else
290 - api.metric = 0;
292 - if (command == ZEBRA_IPV4_ROUTE_ADD)
294 - if (BGP_DEBUG(zebra, ZEBRA))
296 - char buf[2][INET_ADDRSTRLEN];
297 - zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u",
298 - zebra_route_string(api.type),
299 - inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
300 - p.prefixlen,
301 - inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
302 - api.metric);
304 - bgp_redistribute_add((struct prefix *)&p, &nexthop, api.metric, api.type);
306 - else
307 + zapi_ipv4_route_read (zclient, length, &api, &p);
308 + for (i = 0; i < api.nexthop_num; i++)
310 - if (BGP_DEBUG(zebra, ZEBRA))
312 - char buf[2][INET_ADDRSTRLEN];
313 - zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
314 - "nexthop %s metric %u",
315 - zebra_route_string(api.type),
316 - inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
317 - p.prefixlen,
318 - inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
319 - api.metric);
321 - bgp_redistribute_delete((struct prefix *)&p, api.type);
322 + ifindex = 0;
323 + nexthop.s_addr = 0;
324 + if (CHECK_FLAG (api.nexthop[i].type, ZEBRA_NEXTHOP_IPV4))
325 + nexthop.s_addr = api.nexthop[i].gw.ipv4.s_addr;
327 + if (CHECK_FLAG (api.nexthop[i].type, ZEBRA_NEXTHOP_IFINDEX))
328 + ifindex = api.nexthop[i].intf.index;
330 + if (command == ZEBRA_IPV4_ROUTE_ADD)
332 + if (BGP_DEBUG(zebra, ZEBRA))
334 + char buf[2][INET_ADDRSTRLEN];
335 + zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u",
336 + zebra_route_string(api.type),
337 + inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
338 + p.prefixlen,
339 + inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
340 + api.metric);
342 + bgp_redistribute_add((struct prefix *)&p, &nexthop, api.metric, api.type);
344 + else
346 + if (BGP_DEBUG(zebra, ZEBRA))
348 + char buf[2][INET_ADDRSTRLEN];
349 + zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d "
350 + "nexthop %s metric %u",
351 + zebra_route_string(api.type),
352 + inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])),
353 + p.prefixlen,
354 + inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
355 + api.metric);
357 + bgp_redistribute_delete((struct prefix *)&p, api.type);
361 return 0;
362 @@ -307,80 +287,61 @@
363 static int
364 zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
366 - struct stream *s;
367 struct zapi_ipv6 api;
368 unsigned long ifindex;
369 struct in6_addr nexthop;
370 struct prefix_ipv6 p;
371 + int i;
373 - s = zclient->ibuf;
374 - ifindex = 0;
375 - memset (&nexthop, 0, sizeof (struct in6_addr));
377 - /* Type, flags, message. */
378 - api.type = stream_getc (s);
379 - api.flags = stream_getc (s);
380 - api.message = stream_getc (s);
382 - /* IPv6 prefix. */
383 - memset (&p, 0, sizeof (struct prefix_ipv6));
384 - p.family = AF_INET6;
385 - p.prefixlen = stream_getc (s);
386 - stream_get (&p.prefix, s, PSIZE (p.prefixlen));
388 - /* Nexthop, ifindex, distance, metric. */
389 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
391 - api.nexthop_num = stream_getc (s);
392 - stream_get (&nexthop, s, 16);
394 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
396 - api.ifindex_num = stream_getc (s);
397 - ifindex = stream_getl (s);
399 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
400 - api.distance = stream_getc (s);
401 - else
402 - api.distance = 0;
403 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
404 - api.metric = stream_getl (s);
405 - else
406 - api.metric = 0;
407 + zapi_ipv6_route_read (zclient, length, &api, &p);
409 /* Simply ignore link-local address. */
410 if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
411 return 0;
413 - if (command == ZEBRA_IPV6_ROUTE_ADD)
414 + for (i = 0; i < api.nexthop_num; i++)
416 - if (BGP_DEBUG(zebra, ZEBRA))
418 - char buf[INET6_ADDRSTRLEN];
419 - zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d metric %u",
420 - zebra_route_string(api.type),
421 - inet_ntop(AF_INET6, &p.prefix, buf, sizeof(buf)),
422 - p.prefixlen, api.metric);
424 - bgp_redistribute_add ((struct prefix *)&p, NULL, api.metric, api.type);
426 - else
428 - if (BGP_DEBUG(zebra, ZEBRA))
430 - char buf[INET6_ADDRSTRLEN];
431 - zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d metric %u",
432 - zebra_route_string(api.type),
433 - inet_ntop(AF_INET6, &p.prefix, buf, sizeof(buf)),
434 - p.prefixlen, api.metric);
436 - bgp_redistribute_delete ((struct prefix *) &p, api.type);
438 + ifindex = 0;
439 + memset (&nexthop, 0, sizeof (struct in6_addr));
441 + if (CHECK_FLAG (api.nexthop[i].type, ZEBRA_NEXTHOP_IPV6))
442 + memcpy(&nexthop, &api.nexthop[i].gw.ipv6, 16);
444 + if (CHECK_FLAG (api.nexthop[i].type, ZEBRA_NEXTHOP_IFINDEX))
445 + ifindex = api.nexthop[i].intf.index;
447 + if (command == ZEBRA_IPV6_ROUTE_ADD)
449 + if (BGP_DEBUG(zebra, ZEBRA))
451 + char buf[INET6_ADDRSTRLEN];
452 + zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d metric %u",
453 + zebra_route_string(api.type),
454 + inet_ntop(AF_INET6, &p.prefix, buf, sizeof(buf)),
455 + p.prefixlen, api.metric);
457 + bgp_redistribute_add ((struct prefix *)&p, NULL, api.metric, api.type);
459 + else
461 + if (BGP_DEBUG(zebra, ZEBRA))
463 + char buf[INET6_ADDRSTRLEN];
464 + zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d metric %u",
465 + zebra_route_string(api.type),
466 + inet_ntop(AF_INET6, &p.prefix, buf, sizeof(buf)),
467 + p.prefixlen, api.metric);
469 + bgp_redistribute_delete ((struct prefix *) &p, api.type);
473 return 0;
475 #endif /* HAVE_IPV6 */
478 struct interface *
479 if_lookup_by_ipv4 (struct in_addr *addr)
481 @@ -708,10 +669,19 @@
483 api.type = ZEBRA_ROUTE_BGP;
484 api.message = 0;
486 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
487 api.nexthop_num = 1;
488 - api.nexthop = &nexthop;
489 - api.ifindex_num = 0;
490 + api.nexthop[0].type = ZEBRA_NEXTHOP_IPV4;
491 + api.nexthop[0].gw.ipv4 = info->attr->nexthop;
492 +#ifdef HAVE_MPLS
493 + if (CHECK_FLAG (info->flags, BGP_INFO_MPLS))
495 + SET_FLAG (api.nexthop[0].type, ZEBRA_NEXTHOP_MPLS);
496 + api.nexthop[0].mpls.type = ZEBRA_MPLS_LABEL_GEN;
497 + api.nexthop[0].mpls.u.gen = decode_label(info->extra->tag);
499 +#endif
500 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
501 api.metric = info->attr->med;
503 @@ -782,12 +752,20 @@
504 api.flags = flags;
505 api.type = ZEBRA_ROUTE_BGP;
506 api.message = 0;
508 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
509 api.nexthop_num = 1;
510 - api.nexthop = &nexthop;
511 - SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
512 - api.ifindex_num = 1;
513 - api.ifindex = &ifindex;
514 + api.nexthop[0].type = ZEBRA_NEXTHOP_IPV6|ZEBRA_NEXTHOP_IFINDEX;
515 + memcpy(&api.nexthop[0].gw.ipv6, nexthop, sizeof(*nexthop));
516 + api.nexthop[0].intf.index = ifindex;
517 +#ifdef HAVE_MPLS
518 + if (CHECK_FLAG (info->flags, BGP_INFO_MPLS))
520 + SET_FLAG (api.nexthop[0].type, ZEBRA_NEXTHOP_MPLS);
521 + api.nexthop[0].mpls.type = ZEBRA_MPLS_LABEL_GEN;
522 + api.nexthop[0].mpls.u.gen = decode_label(info->extra->tag);
524 +#endif
525 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
526 api.metric = info->attr->med;
528 @@ -842,10 +820,19 @@
530 api.type = ZEBRA_ROUTE_BGP;
531 api.message = 0;
533 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
534 api.nexthop_num = 1;
535 - api.nexthop = &nexthop;
536 - api.ifindex_num = 0;
537 + api.nexthop[0].type = ZEBRA_NEXTHOP_IPV4;
538 + api.nexthop[0].gw.ipv4 = info->attr->nexthop;
539 +#ifdef HAVE_MPLS
540 + if (CHECK_FLAG (info->flags, BGP_INFO_MPLS))
542 + SET_FLAG (api.nexthop[0].type, ZEBRA_NEXTHOP_MPLS);
543 + api.nexthop[0].mpls.type = ZEBRA_MPLS_LABEL_GEN;
544 + api.nexthop[0].mpls.u.gen = decode_label(info->extra->tag);
546 +#endif
547 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
548 api.metric = info->attr->med;
550 @@ -897,12 +884,20 @@
551 api.flags = flags;
552 api.type = ZEBRA_ROUTE_BGP;
553 api.message = 0;
555 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
556 api.nexthop_num = 1;
557 - api.nexthop = &nexthop;
558 - SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
559 - api.ifindex_num = 1;
560 - api.ifindex = &ifindex;
561 + api.nexthop[0].type = ZEBRA_NEXTHOP_IPV6|ZEBRA_NEXTHOP_IFINDEX;
562 + memcpy(&api.nexthop[0].gw.ipv6, nexthop, sizeof(*nexthop));
563 + api.nexthop[0].intf.index = ifindex;
564 +#ifdef HAVE_MPLS
565 + if (CHECK_FLAG (info->flags, BGP_INFO_MPLS))
567 + SET_FLAG (api.nexthop[0].type, ZEBRA_NEXTHOP_MPLS);
568 + api.nexthop[0].mpls.type = ZEBRA_MPLS_LABEL_GEN;
569 + api.nexthop[0].mpls.u.gen = decode_label(info->extra->tag);
571 +#endif
572 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
573 api.metric = info->attr->med;
575 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/config.h.in quagga-mpls/config.h.in
576 --- quagga/config.h.in 2008-09-04 20:37:35.000000000 -0500
577 +++ quagga-mpls/config.h.in 2008-09-07 20:23:30.000000000 -0500
578 @@ -187,6 +187,9 @@
579 /* Define to 1 if you have the `memset' function. */
580 #undef HAVE_MEMSET
582 +/* Enable MPLS */
583 +#undef HAVE_MPLS
585 /* Define to 1 if you have the <netdb.h> header file. */
586 #undef HAVE_NETDB_H
588 @@ -538,9 +541,15 @@
589 /* KAME IPv6 stack */
590 #undef KAME
592 +/* ldpd vty socket */
593 +#undef LDP_VTYSH_PATH
595 /* Linux IPv6 stack */
596 #undef LINUX_IPV6
598 +/* Linux MPLS */
599 +#undef LINUX_MPLS
601 /* Mask for log files */
602 #undef LOGFILE_MASK
604 @@ -590,6 +599,9 @@
605 /* isisd PID */
606 #undef PATH_ISISD_PID
608 +/* ldpd PID */
609 +#undef PATH_LDPD_PID
611 /* ospf6d PID */
612 #undef PATH_OSPF6D_PID
614 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/configure.ac quagga-mpls/configure.ac
615 --- quagga/configure.ac 2008-09-04 20:37:35.000000000 -0500
616 +++ quagga-mpls/configure.ac 2008-09-07 20:23:30.000000000 -0500
617 @@ -179,10 +179,16 @@
618 dnl ----------------------
619 AC_ARG_ENABLE(vtysh,
620 [ --enable-vtysh include integrated vty shell for Quagga])
621 +AC_ARG_ENABLE(mpls,
622 +[ --enable-mpls turn on MPLS related features and daemons])
623 AC_ARG_ENABLE(ipv6,
624 [ --disable-ipv6 turn off IPv6 related features and daemons])
625 AC_ARG_ENABLE(zebra,
626 [ --disable-zebra do not build zebra daemon])
627 +AC_ARG_ENABLE(ldpd,
628 +[ --disable-ldpd do not build ldpd])
629 +AC_ARG_ENABLE(rsvpd,
630 +[ --disable-rsvpd do not build rsvpd])
631 AC_ARG_ENABLE(bgpd,
632 [ --disable-bgpd do not build bgpd])
633 AC_ARG_ENABLE(ripd,
634 @@ -700,7 +706,7 @@
635 if test x"$opsys" = x"gnu-linux"; then
636 if test "${enable_netlink}" = "yes";then
637 AC_MSG_RESULT(netlink)
638 - RT_METHOD=rt_netlink.o
639 + RT_METHOD="netlink.o rt_netlink.o"
640 AC_DEFINE(HAVE_NETLINK,,netlink)
641 netlink=yes
642 elif test "${enable_netlink}" = "no"; then
643 @@ -709,7 +715,7 @@
644 netlink=no
645 else
646 AC_MSG_RESULT(netlink)
647 - RT_METHOD=rt_netlink.o
648 + RT_METHOD="netlink.o rt_netlink.o"
649 AC_DEFINE(HAVE_NETLINK,,netlink)
650 netlink=yes
652 @@ -1115,6 +1121,39 @@
653 #endif
654 ])dnl
656 +dnl ----------
657 +dnl MPLS check
658 +dnl ----------
659 +MPLS_METHOD=""
660 +AC_MSG_CHECKING(whether this OS has MPLS stack)
661 +AM_CONDITIONAL(MPLS_ENABLED, test "x${enable_mpls}" != "xno")
662 +if test "${enable_mpls}" = "no"; then
663 + enable_ldpd="no"
664 + enable_rsvpd="no"
665 + AC_MSG_RESULT(disabled)
666 +else
667 + if test "x${enable_mpls}" = "xnull"; then
668 + AC_DEFINE(HAVE_MPLS,1,Enable MPLS)
669 + MPLS_METHOD="mpls_null.o"
670 + AC_MSG_RESULT(MPLS Null)
671 + else
672 + AC_EGREP_CPP(yes, [
673 + #include <linux/mpls.h>
674 + #if MPLS_LINUX_VERSION
675 + yes
676 + #endif],
677 + [AC_DEFINE(HAVE_MPLS,1,Enable MPLS)
678 + AC_DEFINE(LINUX_MPLS,1,Linux MPLS)
679 + MPLS_METHOD="mpls_netlink.o"
680 + AC_MSG_RESULT(MPLS Linux)],
681 + [enable_ldpd="no"
682 + enable_rsvpd="no"
683 + AC_MSG_RESULT(no)]
685 + fi
687 +AC_SUBST(MPLS_METHOD)
689 dnl --------------------
690 dnl Daemon disable check
691 dnl --------------------
692 @@ -1142,6 +1181,18 @@
693 OSPFD="ospfd"
696 +if test "${enable_ldpd}" = "no";then
697 + LDPD=""
698 +else
699 + LDPD="ldpd"
702 +if test "${enable_rsvpd}" = "no";then
703 + RSVPD=""
704 +else
705 + RSVPD="rsvpd"
708 if test "${enable_watchquagga}" = "no";then
709 WATCHQUAGGA=""
710 else
711 @@ -1157,7 +1208,6 @@
712 OSPFCLIENT="ospfclient"
718 case "${enable_ripngd}" in
719 @@ -1191,6 +1241,8 @@
721 AC_SUBST(ZEBRA)
722 AC_SUBST(BGPD)
723 +AC_SUBST(LDPD)
724 +AC_SUBST(RSVPD)
725 AC_SUBST(RIPD)
726 AC_SUBST(RIPNGD)
727 AC_SUBST(OSPFD)
728 @@ -1406,6 +1458,8 @@
729 AC_DEFINE_UNQUOTED(PATH_ZEBRA_PID, "$quagga_statedir/zebra.pid",zebra PID)
730 AC_DEFINE_UNQUOTED(PATH_RIPD_PID, "$quagga_statedir/ripd.pid",ripd PID)
731 AC_DEFINE_UNQUOTED(PATH_RIPNGD_PID, "$quagga_statedir/ripngd.pid",ripngd PID)
732 +AC_DEFINE_UNQUOTED(PATH_LDPD_PID, "$quagga_statedir/ldpd.pid",ldpd PID)
733 +AC_DEFINE_UNQUOTED(PATH_RSVPD_PID, "$quagga_statedir/rsvpd.pid",rsvpd PID)
734 AC_DEFINE_UNQUOTED(PATH_BGPD_PID, "$quagga_statedir/bgpd.pid",bgpd PID)
735 AC_DEFINE_UNQUOTED(PATH_OSPFD_PID, "$quagga_statedir/ospfd.pid",ospfd PID)
736 AC_DEFINE_UNQUOTED(PATH_OSPF6D_PID, "$quagga_statedir/ospf6d.pid",ospf6d PID)
737 @@ -1415,6 +1469,8 @@
738 AC_DEFINE_UNQUOTED(ZEBRA_VTYSH_PATH, "$quagga_statedir/zebra.vty",zebra vty socket)
739 AC_DEFINE_UNQUOTED(RIP_VTYSH_PATH, "$quagga_statedir/ripd.vty",rip vty socket)
740 AC_DEFINE_UNQUOTED(RIPNG_VTYSH_PATH, "$quagga_statedir/ripngd.vty",ripng vty socket)
741 +AC_DEFINE_UNQUOTED(LDP_VTYSH_PATH, "$quagga_statedir/ldpd.vty",ldpd vty socket)
742 +AC_DEFINE_UNQUOTED(RSVP_VTYSH_PATH, "$quagga_statedir/rsvpd.vty",rsvpd vty socket)
743 AC_DEFINE_UNQUOTED(BGP_VTYSH_PATH, "$quagga_statedir/bgpd.vty",bgpd vty socket)
744 AC_DEFINE_UNQUOTED(OSPF_VTYSH_PATH, "$quagga_statedir/ospfd.vty",ospfd vty socket)
745 AC_DEFINE_UNQUOTED(OSPF6_VTYSH_PATH, "$quagga_statedir/ospf6d.vty",ospf6d vty socket)
746 @@ -1442,6 +1498,8 @@
748 AC_CONFIG_FILES([Makefile lib/Makefile zebra/Makefile ripd/Makefile
749 ripngd/Makefile bgpd/Makefile ospfd/Makefile watchquagga/Makefile
750 + ldpd/Makefile
751 + rsvpd/Makefile
752 ospf6d/Makefile isisd/Makefile vtysh/Makefile doc/Makefile
753 ospfclient/Makefile tests/Makefile m4/Makefile redhat/Makefile
754 pkgsrc/Makefile
755 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/include/linux/genetlink.h quagga-mpls/include/linux/genetlink.h
756 --- quagga/include/linux/genetlink.h 1969-12-31 18:00:00.000000000 -0600
757 +++ quagga-mpls/include/linux/genetlink.h 2008-08-31 20:59:25.000000000 -0500
758 @@ -0,0 +1,113 @@
759 +#ifndef __LINUX_GENERIC_NETLINK_H
760 +#define __LINUX_GENERIC_NETLINK_H
762 +#include <linux/netlink.h>
764 +#define GENL_NAMSIZ 16 /* length of family name */
766 +#define GENL_MIN_ID NLMSG_MIN_TYPE
767 +#define GENL_MAX_ID 1023
769 +struct genlmsghdr {
770 + __u8 cmd;
771 + __u8 version;
772 + __u16 reserved;
775 +#define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr))
777 +#define GENL_ADMIN_PERM 0x01
778 +#define GENL_CMD_CAP_DO 0x02
779 +#define GENL_CMD_CAP_DUMP 0x04
780 +#define GENL_CMD_CAP_HASPOL 0x08
783 + * List of reserved static generic netlink identifiers:
784 + */
785 +#define GENL_ID_GENERATE 0
786 +#define GENL_ID_CTRL NLMSG_MIN_TYPE
788 +/**************************************************************************
789 + * Controller
790 + **************************************************************************/
792 +enum {
793 + CTRL_CMD_UNSPEC,
794 + CTRL_CMD_NEWFAMILY,
795 + CTRL_CMD_DELFAMILY,
796 + CTRL_CMD_GETFAMILY,
797 + CTRL_CMD_NEWOPS,
798 + CTRL_CMD_DELOPS,
799 + CTRL_CMD_GETOPS,
800 + CTRL_CMD_NEWMCAST_GRP,
801 + CTRL_CMD_DELMCAST_GRP,
802 + CTRL_CMD_GETMCAST_GRP, /* unused */
803 + __CTRL_CMD_MAX,
806 +#define CTRL_CMD_MAX (__CTRL_CMD_MAX - 1)
808 +enum {
809 + CTRL_ATTR_UNSPEC,
810 + CTRL_ATTR_FAMILY_ID,
811 + CTRL_ATTR_FAMILY_NAME,
812 + CTRL_ATTR_VERSION,
813 + CTRL_ATTR_HDRSIZE,
814 + CTRL_ATTR_MAXATTR,
815 + CTRL_ATTR_OPS,
816 + CTRL_ATTR_MCAST_GROUPS,
817 + __CTRL_ATTR_MAX,
820 +#define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1)
822 +enum {
823 + CTRL_ATTR_OP_UNSPEC,
824 + CTRL_ATTR_OP_ID,
825 + CTRL_ATTR_OP_FLAGS,
826 + __CTRL_ATTR_OP_MAX,
829 +#define CTRL_ATTR_OP_MAX (__CTRL_ATTR_OP_MAX - 1)
831 +enum {
832 + CTRL_ATTR_MCAST_GRP_UNSPEC,
833 + CTRL_ATTR_MCAST_GRP_NAME,
834 + CTRL_ATTR_MCAST_GRP_ID,
835 + __CTRL_ATTR_MCAST_GRP_MAX,
838 +#define CTRL_ATTR_MCAST_GRP_MAX (__CTRL_ATTR_MCAST_GRP_MAX - 1)
840 +enum {
841 + MPLS_CMD_UNSPEC,
842 + MPLS_CMD_NEWILM,
843 + MPLS_CMD_DELILM,
844 + MPLS_CMD_GETILM,
845 + MPLS_CMD_NEWNHLFE,
846 + MPLS_CMD_DELNHLFE,
847 + MPLS_CMD_GETNHLFE,
848 + MPLS_CMD_NEWXC,
849 + MPLS_CMD_DELXC,
850 + MPLS_CMD_GETXC,
851 + MPLS_CMD_SETLABELSPACE,
852 + MPLS_CMD_GETLABELSPACE,
853 + __MPLS_CMD_MAX,
856 +#define MPLS_CMD_MAX (__MPLS_CMD_MAX - 1)
858 +enum {
859 + MPLS_ATTR_UNSPEC,
860 + MPLS_ATTR_ILM,
861 + MPLS_ATTR_NHLFE,
862 + MPLS_ATTR_XC,
863 + MPLS_ATTR_LABELSPACE,
864 + MPLS_ATTR_INSTR,
865 + MPLS_ATTR_STATS,
866 + __MPLS_ATTR_MAX,
869 +#define MPLS_ATTR_MAX (__MPLS_ATTR_MAX - 1)
871 +#endif /* __LINUX_GENERIC_NETLINK_H */
872 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/include/linux/mpls.h quagga-mpls/include/linux/mpls.h
873 --- quagga/include/linux/mpls.h 1969-12-31 18:00:00.000000000 -0600
874 +++ quagga-mpls/include/linux/mpls.h 2008-08-31 20:59:25.000000000 -0500
875 @@ -0,0 +1,248 @@
876 +/*****************************************************************************
877 + * MPLS
878 + * An implementation of the MPLS (MultiProtocol Label
879 + * Switching Architecture) for Linux.
881 + * Authors:
882 + * James Leu <jleu@mindspring.com>
883 + * Ramon Casellas <casellas@infres.enst.fr>
885 + * (c) 1999-2004 James Leu <jleu@mindspring.com>
886 + * (c) 2003-2004 Ramon Casellas <casellas@infres.enst.fr>
888 + * include/linux/mpls.h
889 + * Data types and structs used by userspace programs to access MPLS
890 + * forwarding. Most interface with the MPLS subsystem is IOCTL based
892 + * This program is free software; you can redistribute it and/or
893 + * modify it under the terms of the GNU General Public License
894 + * as published by the Free Software Foundation; either version
895 + * 2 of the License, or (at your option) any later version.
896 + ****************************************************************************/
898 +#ifndef _LINUX_MPLS_H_
899 +#define _LINUX_MPLS_H_
901 +#ifdef __KERNEL__
902 +#include <linux/socket.h>
903 +#include <linux/if.h>
904 +#else
905 +#include <sys/socket.h>
906 +#include <linux/types.h>
907 +#include <net/if.h>
908 +#endif
910 +#define MPLS_NUM_OPS 8
912 +#define MPLS_LINUX_VERSION 0x01090602
914 +#define MPLS_GRP_ILM 1
915 +#define MPLS_GRP_NHLFE 2
916 +#define MPLS_GRP_XC 4
917 +#define MPLS_GRP_LABELSPACE 8
919 +#define MPLS_IPV4_EXPLICIT_NULL 0 /* only valid as sole label stack entry
920 + Pop label and send to IPv4 stack */
921 +#define MPLS_ROUTER_ALERT 1 /* anywhere except bottom, packet it is
922 + forwared to a software module
923 + determined by the next label,
924 + if the packet is forwarded, push this
925 + label back on */
926 +#define MPLS_IPV6_EXPLICIT_NULL 2 /* only valid as sole label stack entry
927 + Pop label and send to IPv6 stack */
928 +#define MPLS_IMPLICIT_NULL 3 /* a LIB with this, signifies to pop
929 + the next label and use that */
931 +#define MPLS_CHANGE_MTU 0x01
932 +#define MPLS_CHANGE_PROP_TTL 0x02
933 +#define MPLS_CHANGE_INSTR 0x04
934 +#define MPLS_CHANGE_PROTO 0x10
936 +enum mpls_dir {
937 + MPLS_IN = 0x10,
938 + MPLS_OUT = 0x20
941 +enum mpls_opcode_enum {
942 + MPLS_OP_NOP = 0x00,
943 + MPLS_OP_POP,
944 + MPLS_OP_PEEK,
945 + MPLS_OP_PUSH,
946 + MPLS_OP_DLV,
947 + MPLS_OP_FWD,
948 + MPLS_OP_NF_FWD,
949 + MPLS_OP_DS_FWD,
950 + MPLS_OP_EXP_FWD,
951 + MPLS_OP_SET,
952 + MPLS_OP_SET_RX,
953 + MPLS_OP_SET_TC,
954 + MPLS_OP_SET_DS,
955 + MPLS_OP_SET_EXP,
956 + MPLS_OP_EXP2TC,
957 + MPLS_OP_EXP2DS,
958 + MPLS_OP_TC2EXP,
959 + MPLS_OP_DS2EXP,
960 + MPLS_OP_NF2EXP,
961 + MPLS_OP_SET_NF,
962 + MPLS_OP_MAX
965 +enum mpls_label_type_enum {
966 + MPLS_LABEL_GEN = 1,
967 + MPLS_LABEL_ATM,
968 + MPLS_LABEL_FR,
969 + MPLS_LABEL_KEY
972 +struct mpls_label_atm {
973 + u_int16_t mla_vpi;
974 + u_int16_t mla_vci;
977 +struct mpls_label {
978 + enum mpls_label_type_enum ml_type;
979 + union {
980 + u_int32_t ml_key;
981 + u_int32_t ml_gen;
982 + u_int32_t ml_fr;
983 + struct mpls_label_atm ml_atm;
984 + } u;
985 + int ml_index;
988 +struct mpls_in_label_req {
989 + unsigned int mil_proto;
990 + struct mpls_label mil_label;
991 + unsigned char mil_change_flag;
994 +#define MPLS_LABELSPACE_MAX 255
996 +struct mpls_labelspace_req {
997 + int mls_ifindex; /* Index to the MPLS-enab. interface*/
998 + int mls_labelspace; /* Labelspace IN/SET -- OUT/GET */
1001 +struct mpls_nexthop_info {
1002 + unsigned int mni_if;
1003 + struct sockaddr mni_addr;
1006 +struct mpls_out_label_req {
1007 + struct mpls_label mol_label;
1008 + u_int32_t mol_mtu;
1009 + int8_t mol_propagate_ttl;
1010 + unsigned char mol_change_flag;
1013 +struct mpls_xconnect_req {
1014 + struct mpls_label mx_in;
1015 + struct mpls_label mx_out;
1018 +struct mpls_tunnel_req {
1019 + char mt_ifname[IFNAMSIZ];
1020 + unsigned int mt_nhlfe_key;
1023 +#define MPLS_NFMARK_NUM 64
1025 +struct mpls_nfmark_fwd {
1026 + unsigned int nf_key[MPLS_NFMARK_NUM];
1027 + unsigned short nf_mask;
1030 +#define MPLS_DSMARK_NUM 64
1032 +struct mpls_dsmark_fwd {
1033 + unsigned int df_key[MPLS_DSMARK_NUM];
1034 + unsigned char df_mask;
1037 +#define MPLS_TCINDEX_NUM 64
1039 +struct mpls_tcindex_fwd {
1040 + unsigned int tc_key[MPLS_TCINDEX_NUM];
1041 + unsigned short tc_mask;
1044 +#define MPLS_EXP_NUM 8
1046 +struct mpls_exp_fwd {
1047 + unsigned int ef_key[MPLS_EXP_NUM];
1050 +struct mpls_exp2tcindex {
1051 + unsigned short e2t[MPLS_EXP_NUM];
1054 +struct mpls_exp2dsmark {
1055 + unsigned char e2d[MPLS_EXP_NUM];
1058 +struct mpls_tcindex2exp {
1059 + unsigned char t2e_mask;
1060 + unsigned char t2e[MPLS_TCINDEX_NUM];
1063 +struct mpls_dsmark2exp {
1064 + unsigned char d2e_mask;
1065 + unsigned char d2e[MPLS_DSMARK_NUM];
1068 +struct mpls_nfmark2exp {
1069 + unsigned char n2e_mask;
1070 + unsigned char n2e[MPLS_NFMARK_NUM];
1073 +struct mpls_instr_elem {
1074 + unsigned short mir_opcode;
1075 + unsigned char mir_direction;
1076 + union {
1077 + struct mpls_label push;
1078 + struct mpls_label fwd;
1079 + struct mpls_nfmark_fwd nf_fwd;
1080 + struct mpls_dsmark_fwd ds_fwd;
1081 + struct mpls_exp_fwd exp_fwd;
1082 + struct mpls_nexthop_info set;
1083 + unsigned int set_rx;
1084 + unsigned short set_tc;
1085 + unsigned short set_ds;
1086 + unsigned char set_exp;
1087 + struct mpls_exp2tcindex exp2tc;
1088 + struct mpls_exp2dsmark exp2ds;
1089 + struct mpls_tcindex2exp tc2exp;
1090 + struct mpls_dsmark2exp ds2exp;
1091 + struct mpls_nfmark2exp nf2exp;
1092 + unsigned long set_nf;
1093 + } mir_data;
1096 +/* Standard shortcuts */
1097 +#define mir_push mir_data.push
1098 +#define mir_fwd mir_data.fwd
1099 +#define mir_nf_fwd mir_data.nf_fwd
1100 +#define mir_ds_fwd mir_data.ds_fwd
1101 +#define mir_exp_fwd mir_data.exp_fwd
1102 +#define mir_set mir_data.set
1103 +#define mir_set_rx mir_data.set_rx
1104 +#define mir_set_tc mir_data.set_tc
1105 +#define mir_set_tx mir_data.set_tx
1106 +#define mir_set_ds mir_data.set_ds
1107 +#define mir_set_exp mir_data.set_exp
1108 +#define mir_set_nf mir_data.set_nf
1109 +#define mir_exp2tc mir_data.exp2tc
1110 +#define mir_exp2ds mir_data.exp2ds
1111 +#define mir_tc2exp mir_data.tc2exp
1112 +#define mir_ds2exp mir_data.ds2exp
1113 +#define mir_nf2exp mir_data.nf2exp
1115 +struct mpls_instr_req {
1116 + struct mpls_instr_elem mir_instr[MPLS_NUM_OPS];
1117 + unsigned char mir_instr_length;
1118 + unsigned char mir_direction;
1119 + int mir_index;
1120 + struct mpls_label mir_label;
1123 +#endif
1124 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/include/linux/rtnetlink.h quagga-mpls/include/linux/rtnetlink.h
1125 --- quagga/include/linux/rtnetlink.h 1969-12-31 18:00:00.000000000 -0600
1126 +++ quagga-mpls/include/linux/rtnetlink.h 2008-08-31 20:59:25.000000000 -0500
1127 @@ -0,0 +1,774 @@
1128 +#ifndef __LINUX_RTNETLINK_H
1129 +#define __LINUX_RTNETLINK_H
1131 +#include <linux/netlink.h>
1132 +#include <linux/if_link.h>
1133 +#include <linux/if_addr.h>
1134 +#include <linux/neighbour.h>
1136 +/****
1137 + * Routing/neighbour discovery messages.
1138 + ****/
1140 +/* Types of messages */
1142 +enum {
1143 + RTM_BASE = 16,
1144 +#define RTM_BASE RTM_BASE
1146 + RTM_NEWLINK = 16,
1147 +#define RTM_NEWLINK RTM_NEWLINK
1148 + RTM_DELLINK,
1149 +#define RTM_DELLINK RTM_DELLINK
1150 + RTM_GETLINK,
1151 +#define RTM_GETLINK RTM_GETLINK
1152 + RTM_SETLINK,
1153 +#define RTM_SETLINK RTM_SETLINK
1155 + RTM_NEWADDR = 20,
1156 +#define RTM_NEWADDR RTM_NEWADDR
1157 + RTM_DELADDR,
1158 +#define RTM_DELADDR RTM_DELADDR
1159 + RTM_GETADDR,
1160 +#define RTM_GETADDR RTM_GETADDR
1162 + RTM_NEWROUTE = 24,
1163 +#define RTM_NEWROUTE RTM_NEWROUTE
1164 + RTM_DELROUTE,
1165 +#define RTM_DELROUTE RTM_DELROUTE
1166 + RTM_GETROUTE,
1167 +#define RTM_GETROUTE RTM_GETROUTE
1169 + RTM_NEWNEIGH = 28,
1170 +#define RTM_NEWNEIGH RTM_NEWNEIGH
1171 + RTM_DELNEIGH,
1172 +#define RTM_DELNEIGH RTM_DELNEIGH
1173 + RTM_GETNEIGH,
1174 +#define RTM_GETNEIGH RTM_GETNEIGH
1176 + RTM_NEWRULE = 32,
1177 +#define RTM_NEWRULE RTM_NEWRULE
1178 + RTM_DELRULE,
1179 +#define RTM_DELRULE RTM_DELRULE
1180 + RTM_GETRULE,
1181 +#define RTM_GETRULE RTM_GETRULE
1183 + RTM_NEWQDISC = 36,
1184 +#define RTM_NEWQDISC RTM_NEWQDISC
1185 + RTM_DELQDISC,
1186 +#define RTM_DELQDISC RTM_DELQDISC
1187 + RTM_GETQDISC,
1188 +#define RTM_GETQDISC RTM_GETQDISC
1190 + RTM_NEWTCLASS = 40,
1191 +#define RTM_NEWTCLASS RTM_NEWTCLASS
1192 + RTM_DELTCLASS,
1193 +#define RTM_DELTCLASS RTM_DELTCLASS
1194 + RTM_GETTCLASS,
1195 +#define RTM_GETTCLASS RTM_GETTCLASS
1197 + RTM_NEWTFILTER = 44,
1198 +#define RTM_NEWTFILTER RTM_NEWTFILTER
1199 + RTM_DELTFILTER,
1200 +#define RTM_DELTFILTER RTM_DELTFILTER
1201 + RTM_GETTFILTER,
1202 +#define RTM_GETTFILTER RTM_GETTFILTER
1204 + RTM_NEWACTION = 48,
1205 +#define RTM_NEWACTION RTM_NEWACTION
1206 + RTM_DELACTION,
1207 +#define RTM_DELACTION RTM_DELACTION
1208 + RTM_GETACTION,
1209 +#define RTM_GETACTION RTM_GETACTION
1211 + RTM_NEWPREFIX = 52,
1212 +#define RTM_NEWPREFIX RTM_NEWPREFIX
1214 + RTM_GETMULTICAST = 58,
1215 +#define RTM_GETMULTICAST RTM_GETMULTICAST
1217 + RTM_GETANYCAST = 62,
1218 +#define RTM_GETANYCAST RTM_GETANYCAST
1220 + RTM_NEWNEIGHTBL = 64,
1221 +#define RTM_NEWNEIGHTBL RTM_NEWNEIGHTBL
1222 + RTM_GETNEIGHTBL = 66,
1223 +#define RTM_GETNEIGHTBL RTM_GETNEIGHTBL
1224 + RTM_SETNEIGHTBL,
1225 +#define RTM_SETNEIGHTBL RTM_SETNEIGHTBL
1227 + RTM_NEWNDUSEROPT = 68,
1228 +#define RTM_NEWNDUSEROPT RTM_NEWNDUSEROPT
1230 + RTM_NEWADDRLABEL = 72,
1231 +#define RTM_NEWADDRLABEL RTM_NEWADDRLABEL
1232 + RTM_DELADDRLABEL,
1233 +#define RTM_NEWADDRLABEL RTM_NEWADDRLABEL
1234 + RTM_GETADDRLABEL,
1235 +#define RTM_GETADDRLABEL RTM_GETADDRLABEL
1237 + __RTM_MAX,
1238 +#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
1241 +#define RTM_NR_MSGTYPES (RTM_MAX + 1 - RTM_BASE)
1242 +#define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2)
1243 +#define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2)
1245 +/*
1246 + Generic structure for encapsulation of optional route information.
1247 + It is reminiscent of sockaddr, but with sa_family replaced
1248 + with attribute type.
1249 + */
1251 +struct rtattr
1253 + unsigned short rta_len;
1254 + unsigned short rta_type;
1257 +/* Macros to handle rtattributes */
1259 +#define RTA_ALIGNTO 4
1260 +#define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) )
1261 +#define RTA_OK(rta,len) ((len) >= (int)sizeof(struct rtattr) && \
1262 + (rta)->rta_len >= sizeof(struct rtattr) && \
1263 + (rta)->rta_len <= (len))
1264 +#define RTA_NEXT(rta,attrlen) ((attrlen) -= RTA_ALIGN((rta)->rta_len), \
1265 + (struct rtattr*)(((char*)(rta)) + RTA_ALIGN((rta)->rta_len)))
1266 +#define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
1267 +#define RTA_SPACE(len) RTA_ALIGN(RTA_LENGTH(len))
1268 +#define RTA_DATA(rta) ((void*)(((char*)(rta)) + RTA_LENGTH(0)))
1269 +#define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
1274 +/******************************************************************************
1275 + * Definitions used in routing table administration.
1276 + ****/
1278 +struct rtmsg
1280 + unsigned char rtm_family;
1281 + unsigned char rtm_dst_len;
1282 + unsigned char rtm_src_len;
1283 + unsigned char rtm_tos;
1285 + unsigned char rtm_table; /* Routing table id */
1286 + unsigned char rtm_protocol; /* Routing protocol; see below */
1287 + unsigned char rtm_scope; /* See below */
1288 + unsigned char rtm_type; /* See below */
1290 + unsigned rtm_flags;
1293 +/* rtm_type */
1295 +enum
1297 + RTN_UNSPEC,
1298 + RTN_UNICAST, /* Gateway or direct route */
1299 + RTN_LOCAL, /* Accept locally */
1300 + RTN_BROADCAST, /* Accept locally as broadcast,
1301 + send as broadcast */
1302 + RTN_ANYCAST, /* Accept locally as broadcast,
1303 + but send as unicast */
1304 + RTN_MULTICAST, /* Multicast route */
1305 + RTN_BLACKHOLE, /* Drop */
1306 + RTN_UNREACHABLE, /* Destination is unreachable */
1307 + RTN_PROHIBIT, /* Administratively prohibited */
1308 + RTN_THROW, /* Not in this table */
1309 + RTN_NAT, /* Translate this address */
1310 + RTN_XRESOLVE, /* Use external resolver */
1311 + __RTN_MAX
1314 +#define RTN_MAX (__RTN_MAX - 1)
1317 +/* rtm_protocol */
1319 +#define RTPROT_UNSPEC 0
1320 +#define RTPROT_REDIRECT 1 /* Route installed by ICMP redirects;
1321 + not used by current IPv4 */
1322 +#define RTPROT_KERNEL 2 /* Route installed by kernel */
1323 +#define RTPROT_BOOT 3 /* Route installed during boot */
1324 +#define RTPROT_STATIC 4 /* Route installed by administrator */
1326 +/* Values of protocol >= RTPROT_STATIC are not interpreted by kernel;
1327 + they are just passed from user and back as is.
1328 + It will be used by hypothetical multiple routing daemons.
1329 + Note that protocol values should be standardized in order to
1330 + avoid conflicts.
1331 + */
1333 +#define RTPROT_GATED 8 /* Apparently, GateD */
1334 +#define RTPROT_RA 9 /* RDISC/ND router advertisements */
1335 +#define RTPROT_MRT 10 /* Merit MRT */
1336 +#define RTPROT_ZEBRA 11 /* Zebra */
1337 +#define RTPROT_BIRD 12 /* BIRD */
1338 +#define RTPROT_DNROUTED 13 /* DECnet routing daemon */
1339 +#define RTPROT_XORP 14 /* XORP */
1340 +#define RTPROT_NTK 15 /* Netsukuku */
1342 +/* rtm_scope
1344 + Really it is not scope, but sort of distance to the destination.
1345 + NOWHERE are reserved for not existing destinations, HOST is our
1346 + local addresses, LINK are destinations, located on directly attached
1347 + link and UNIVERSE is everywhere in the Universe.
1349 + Intermediate values are also possible f.e. interior routes
1350 + could be assigned a value between UNIVERSE and LINK.
1353 +enum rt_scope_t
1355 + RT_SCOPE_UNIVERSE=0,
1356 +/* User defined values */
1357 + RT_SCOPE_SITE=200,
1358 + RT_SCOPE_LINK=253,
1359 + RT_SCOPE_HOST=254,
1360 + RT_SCOPE_NOWHERE=255
1363 +/* rtm_flags */
1365 +#define RTM_F_NOTIFY 0x100 /* Notify user of route change */
1366 +#define RTM_F_CLONED 0x200 /* This route is cloned */
1367 +#define RTM_F_EQUALIZE 0x400 /* Multipath equalizer: NI */
1368 +#define RTM_F_PREFIX 0x800 /* Prefix addresses */
1370 +/* Reserved table identifiers */
1372 +enum rt_class_t
1374 + RT_TABLE_UNSPEC=0,
1375 +/* User defined values */
1376 + RT_TABLE_DEFAULT=253,
1377 + RT_TABLE_MAIN=254,
1378 + RT_TABLE_LOCAL=255,
1379 + RT_TABLE_MAX=0xFFFFFFFF
1383 +/* Routing message attributes */
1385 +enum rtattr_type_t
1387 + RTA_UNSPEC,
1388 + RTA_DST,
1389 + RTA_SRC,
1390 + RTA_IIF,
1391 + RTA_OIF,
1392 + RTA_GATEWAY,
1393 + RTA_PRIORITY,
1394 + RTA_PREFSRC,
1395 + RTA_METRICS,
1396 + RTA_MULTIPATH,
1397 + RTA_PROTOINFO,
1398 + RTA_FLOW,
1399 + RTA_CACHEINFO,
1400 + RTA_SESSION,
1401 + RTA_MP_ALGO, /* no longer used */
1402 + RTA_TABLE,
1403 + RTA_SHIM = 30,
1404 + __RTA_MAX
1407 +#define RTA_MAX (__RTA_MAX - 1)
1409 +#define RTM_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg))))
1410 +#define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtmsg))
1412 +/* RTM_MULTIPATH --- array of struct rtnexthop.
1414 + * "struct rtnexthop" describes all necessary nexthop information,
1415 + * i.e. parameters of path to a destination via this nexthop.
1417 + * At the moment it is impossible to set different prefsrc, mtu, window
1418 + * and rtt for different paths from multipath.
1419 + */
1421 +struct rtnexthop
1423 + unsigned short rtnh_len;
1424 + unsigned char rtnh_flags;
1425 + unsigned char rtnh_hops;
1426 + int rtnh_ifindex;
1429 +/* rtnh_flags */
1431 +#define RTNH_F_DEAD 1 /* Nexthop is dead (used by multipath) */
1432 +#define RTNH_F_PERVASIVE 2 /* Do recursive gateway lookup */
1433 +#define RTNH_F_ONLINK 4 /* Gateway is forced on link */
1435 +/* Macros to handle hexthops */
1437 +#define RTNH_ALIGNTO 4
1438 +#define RTNH_ALIGN(len) ( ((len)+RTNH_ALIGNTO-1) & ~(RTNH_ALIGNTO-1) )
1439 +#define RTNH_OK(rtnh,len) ((rtnh)->rtnh_len >= sizeof(struct rtnexthop) && \
1440 + ((int)(rtnh)->rtnh_len) <= (len))
1441 +#define RTNH_NEXT(rtnh) ((struct rtnexthop*)(((char*)(rtnh)) + RTNH_ALIGN((rtnh)->rtnh_len)))
1442 +#define RTNH_LENGTH(len) (RTNH_ALIGN(sizeof(struct rtnexthop)) + (len))
1443 +#define RTNH_SPACE(len) RTNH_ALIGN(RTNH_LENGTH(len))
1444 +#define RTNH_DATA(rtnh) ((struct rtattr*)(((char*)(rtnh)) + RTNH_LENGTH(0)))
1446 +/* RTM_CACHEINFO */
1448 +struct rta_cacheinfo
1450 + __u32 rta_clntref;
1451 + __u32 rta_lastuse;
1452 + __s32 rta_expires;
1453 + __u32 rta_error;
1454 + __u32 rta_used;
1456 +#define RTNETLINK_HAVE_PEERINFO 1
1457 + __u32 rta_id;
1458 + __u32 rta_ts;
1459 + __u32 rta_tsage;
1462 +/* RTM_METRICS --- array of struct rtattr with types of RTAX_* */
1464 +enum
1466 + RTAX_UNSPEC,
1467 +#define RTAX_UNSPEC RTAX_UNSPEC
1468 + RTAX_LOCK,
1469 +#define RTAX_LOCK RTAX_LOCK
1470 + RTAX_MTU,
1471 +#define RTAX_MTU RTAX_MTU
1472 + RTAX_WINDOW,
1473 +#define RTAX_WINDOW RTAX_WINDOW
1474 + RTAX_RTT,
1475 +#define RTAX_RTT RTAX_RTT
1476 + RTAX_RTTVAR,
1477 +#define RTAX_RTTVAR RTAX_RTTVAR
1478 + RTAX_SSTHRESH,
1479 +#define RTAX_SSTHRESH RTAX_SSTHRESH
1480 + RTAX_CWND,
1481 +#define RTAX_CWND RTAX_CWND
1482 + RTAX_ADVMSS,
1483 +#define RTAX_ADVMSS RTAX_ADVMSS
1484 + RTAX_REORDERING,
1485 +#define RTAX_REORDERING RTAX_REORDERING
1486 + RTAX_HOPLIMIT,
1487 +#define RTAX_HOPLIMIT RTAX_HOPLIMIT
1488 + RTAX_INITCWND,
1489 +#define RTAX_INITCWND RTAX_INITCWND
1490 + RTAX_FEATURES,
1491 +#define RTAX_FEATURES RTAX_FEATURES
1492 + RTAX_RTO_MIN,
1493 +#define RTAX_RTO_MIN RTAX_RTO_MIN
1494 + __RTAX_MAX
1497 +#define RTAX_MAX (__RTAX_MAX - 1)
1499 +#define RTAX_FEATURE_ECN 0x00000001
1500 +#define RTAX_FEATURE_SACK 0x00000002
1501 +#define RTAX_FEATURE_TIMESTAMP 0x00000004
1502 +#define RTAX_FEATURE_ALLFRAG 0x00000008
1504 +struct rta_session
1506 + __u8 proto;
1507 + __u8 pad1;
1508 + __u16 pad2;
1510 + union {
1511 + struct {
1512 + __u16 sport;
1513 + __u16 dport;
1514 + } ports;
1516 + struct {
1517 + __u8 type;
1518 + __u8 code;
1519 + __u16 ident;
1520 + } icmpt;
1522 + __u32 spi;
1523 + } u;
1526 +/****
1527 + * General form of address family dependent message.
1528 + ****/
1530 +struct rtgenmsg
1532 + unsigned char rtgen_family;
1535 +/*****************************************************************
1536 + * Link layer specific messages.
1537 + ****/
1539 +/* struct ifinfomsg
1540 + * passes link level specific information, not dependent
1541 + * on network protocol.
1542 + */
1544 +struct ifinfomsg
1546 + unsigned char ifi_family;
1547 + unsigned char __ifi_pad;
1548 + unsigned short ifi_type; /* ARPHRD_* */
1549 + int ifi_index; /* Link index */
1550 + unsigned ifi_flags; /* IFF_* flags */
1551 + unsigned ifi_change; /* IFF_* change mask */
1554 +/********************************************************************
1555 + * prefix information
1556 + ****/
1558 +struct prefixmsg
1560 + unsigned char prefix_family;
1561 + unsigned char prefix_pad1;
1562 + unsigned short prefix_pad2;
1563 + int prefix_ifindex;
1564 + unsigned char prefix_type;
1565 + unsigned char prefix_len;
1566 + unsigned char prefix_flags;
1567 + unsigned char prefix_pad3;
1570 +enum
1572 + PREFIX_UNSPEC,
1573 + PREFIX_ADDRESS,
1574 + PREFIX_CACHEINFO,
1575 + __PREFIX_MAX
1578 +#define PREFIX_MAX (__PREFIX_MAX - 1)
1580 +struct prefix_cacheinfo
1582 + __u32 preferred_time;
1583 + __u32 valid_time;
1587 +/*****************************************************************
1588 + * Traffic control messages.
1589 + ****/
1591 +struct tcmsg
1593 + unsigned char tcm_family;
1594 + unsigned char tcm__pad1;
1595 + unsigned short tcm__pad2;
1596 + int tcm_ifindex;
1597 + __u32 tcm_handle;
1598 + __u32 tcm_parent;
1599 + __u32 tcm_info;
1602 +enum
1604 + TCA_UNSPEC,
1605 + TCA_KIND,
1606 + TCA_OPTIONS,
1607 + TCA_STATS,
1608 + TCA_XSTATS,
1609 + TCA_RATE,
1610 + TCA_FCNT,
1611 + TCA_STATS2,
1612 + __TCA_MAX
1615 +#define TCA_MAX (__TCA_MAX - 1)
1617 +#define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
1618 +#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
1620 +/********************************************************************
1621 + * Neighbor Discovery userland options
1622 + ****/
1624 +struct nduseroptmsg
1626 + unsigned char nduseropt_family;
1627 + unsigned char nduseropt_pad1;
1628 + unsigned short nduseropt_opts_len; /* Total length of options */
1629 + int nduseropt_ifindex;
1630 + __u8 nduseropt_icmp_type;
1631 + __u8 nduseropt_icmp_code;
1632 + unsigned short nduseropt_pad2;
1633 + unsigned int nduseropt_pad3;
1634 + /* Followed by one or more ND options */
1637 +enum
1639 + NDUSEROPT_UNSPEC,
1640 + NDUSEROPT_SRCADDR,
1641 + __NDUSEROPT_MAX
1644 +#define NDUSEROPT_MAX (__NDUSEROPT_MAX - 1)
1646 +#ifndef __KERNEL__
1647 +/* RTnetlink multicast groups - backwards compatibility for userspace */
1648 +#define RTMGRP_LINK 1
1649 +#define RTMGRP_NOTIFY 2
1650 +#define RTMGRP_NEIGH 4
1651 +#define RTMGRP_TC 8
1653 +#define RTMGRP_IPV4_IFADDR 0x10
1654 +#define RTMGRP_IPV4_MROUTE 0x20
1655 +#define RTMGRP_IPV4_ROUTE 0x40
1656 +#define RTMGRP_IPV4_RULE 0x80
1658 +#define RTMGRP_IPV6_IFADDR 0x100
1659 +#define RTMGRP_IPV6_MROUTE 0x200
1660 +#define RTMGRP_IPV6_ROUTE 0x400
1661 +#define RTMGRP_IPV6_IFINFO 0x800
1663 +#define RTMGRP_DECnet_IFADDR 0x1000
1664 +#define RTMGRP_DECnet_ROUTE 0x4000
1666 +#define RTMGRP_IPV6_PREFIX 0x20000
1667 +#endif
1669 +/* RTnetlink multicast groups */
1670 +enum rtnetlink_groups {
1671 + RTNLGRP_NONE,
1672 +#define RTNLGRP_NONE RTNLGRP_NONE
1673 + RTNLGRP_LINK,
1674 +#define RTNLGRP_LINK RTNLGRP_LINK
1675 + RTNLGRP_NOTIFY,
1676 +#define RTNLGRP_NOTIFY RTNLGRP_NOTIFY
1677 + RTNLGRP_NEIGH,
1678 +#define RTNLGRP_NEIGH RTNLGRP_NEIGH
1679 + RTNLGRP_TC,
1680 +#define RTNLGRP_TC RTNLGRP_TC
1681 + RTNLGRP_IPV4_IFADDR,
1682 +#define RTNLGRP_IPV4_IFADDR RTNLGRP_IPV4_IFADDR
1683 + RTNLGRP_IPV4_MROUTE,
1684 +#define RTNLGRP_IPV4_MROUTE RTNLGRP_IPV4_MROUTE
1685 + RTNLGRP_IPV4_ROUTE,
1686 +#define RTNLGRP_IPV4_ROUTE RTNLGRP_IPV4_ROUTE
1687 + RTNLGRP_IPV4_RULE,
1688 +#define RTNLGRP_IPV4_RULE RTNLGRP_IPV4_RULE
1689 + RTNLGRP_IPV6_IFADDR,
1690 +#define RTNLGRP_IPV6_IFADDR RTNLGRP_IPV6_IFADDR
1691 + RTNLGRP_IPV6_MROUTE,
1692 +#define RTNLGRP_IPV6_MROUTE RTNLGRP_IPV6_MROUTE
1693 + RTNLGRP_IPV6_ROUTE,
1694 +#define RTNLGRP_IPV6_ROUTE RTNLGRP_IPV6_ROUTE
1695 + RTNLGRP_IPV6_IFINFO,
1696 +#define RTNLGRP_IPV6_IFINFO RTNLGRP_IPV6_IFINFO
1697 + RTNLGRP_DECnet_IFADDR,
1698 +#define RTNLGRP_DECnet_IFADDR RTNLGRP_DECnet_IFADDR
1699 + RTNLGRP_NOP2,
1700 + RTNLGRP_DECnet_ROUTE,
1701 +#define RTNLGRP_DECnet_ROUTE RTNLGRP_DECnet_ROUTE
1702 + RTNLGRP_DECnet_RULE,
1703 +#define RTNLGRP_DECnet_RULE RTNLGRP_DECnet_RULE
1704 + RTNLGRP_NOP4,
1705 + RTNLGRP_IPV6_PREFIX,
1706 +#define RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_PREFIX
1707 + RTNLGRP_IPV6_RULE,
1708 +#define RTNLGRP_IPV6_RULE RTNLGRP_IPV6_RULE
1709 + RTNLGRP_ND_USEROPT,
1710 +#define RTNLGRP_ND_USEROPT RTNLGRP_ND_USEROPT
1711 + __RTNLGRP_MAX
1713 +#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
1715 +/* TC action piece */
1716 +struct tcamsg
1718 + unsigned char tca_family;
1719 + unsigned char tca__pad1;
1720 + unsigned short tca__pad2;
1722 +#define TA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcamsg))))
1723 +#define TA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcamsg))
1724 +#define TCA_ACT_TAB 1 /* attr type must be >=1 */
1725 +#define TCAA_MAX 1
1727 +/* End of information exported to user level */
1729 +#ifdef __KERNEL__
1731 +#include <linux/mutex.h>
1733 +static __inline__ int rtattr_strcmp(const struct rtattr *rta, const char *str)
1735 + int len = strlen(str) + 1;
1736 + return len > rta->rta_len || memcmp(RTA_DATA(rta), str, len);
1739 +extern int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, u32 group, int echo);
1740 +extern int rtnl_unicast(struct sk_buff *skb, struct net *net, u32 pid);
1741 +extern int rtnl_notify(struct sk_buff *skb, struct net *net, u32 pid, u32 group,
1742 + struct nlmsghdr *nlh, gfp_t flags);
1743 +extern void rtnl_set_sk_err(struct net *net, u32 group, int error);
1744 +extern int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics);
1745 +extern int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst,
1746 + u32 id, u32 ts, u32 tsage, long expires,
1747 + u32 error);
1749 +extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data);
1751 +#define RTA_PUT(skb, attrtype, attrlen, data) \
1752 +({ if (unlikely(skb_tailroom(skb) < (int)RTA_SPACE(attrlen))) \
1753 + goto rtattr_failure; \
1754 + __rta_fill(skb, attrtype, attrlen, data); })
1756 +#define RTA_APPEND(skb, attrlen, data) \
1757 +({ if (unlikely(skb_tailroom(skb) < (int)(attrlen))) \
1758 + goto rtattr_failure; \
1759 + memcpy(skb_put(skb, attrlen), data, attrlen); })
1761 +#define RTA_PUT_NOHDR(skb, attrlen, data) \
1762 +({ RTA_APPEND(skb, RTA_ALIGN(attrlen), data); \
1763 + memset(skb_tail_pointer(skb) - (RTA_ALIGN(attrlen) - attrlen), 0, \
1764 + RTA_ALIGN(attrlen) - attrlen); })
1766 +#define RTA_PUT_U8(skb, attrtype, value) \
1767 +({ u8 _tmp = (value); \
1768 + RTA_PUT(skb, attrtype, sizeof(u8), &_tmp); })
1770 +#define RTA_PUT_U16(skb, attrtype, value) \
1771 +({ u16 _tmp = (value); \
1772 + RTA_PUT(skb, attrtype, sizeof(u16), &_tmp); })
1774 +#define RTA_PUT_U32(skb, attrtype, value) \
1775 +({ u32 _tmp = (value); \
1776 + RTA_PUT(skb, attrtype, sizeof(u32), &_tmp); })
1778 +#define RTA_PUT_U64(skb, attrtype, value) \
1779 +({ u64 _tmp = (value); \
1780 + RTA_PUT(skb, attrtype, sizeof(u64), &_tmp); })
1782 +#define RTA_PUT_SECS(skb, attrtype, value) \
1783 + RTA_PUT_U64(skb, attrtype, (value) / HZ)
1785 +#define RTA_PUT_MSECS(skb, attrtype, value) \
1786 + RTA_PUT_U64(skb, attrtype, jiffies_to_msecs(value))
1788 +#define RTA_PUT_STRING(skb, attrtype, value) \
1789 + RTA_PUT(skb, attrtype, strlen(value) + 1, value)
1791 +#define RTA_PUT_FLAG(skb, attrtype) \
1792 + RTA_PUT(skb, attrtype, 0, NULL);
1794 +#define RTA_NEST(skb, type) \
1795 +({ struct rtattr *__start = (struct rtattr *)skb_tail_pointer(skb); \
1796 + RTA_PUT(skb, type, 0, NULL); \
1797 + __start; })
1799 +#define RTA_NEST_END(skb, start) \
1800 +({ (start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
1801 + (skb)->len; })
1803 +#define RTA_NEST_COMPAT(skb, type, attrlen, data) \
1804 +({ struct rtattr *__start = (struct rtattr *)skb_tail_pointer(skb); \
1805 + RTA_PUT(skb, type, attrlen, data); \
1806 + RTA_NEST(skb, type); \
1807 + __start; })
1809 +#define RTA_NEST_COMPAT_END(skb, start) \
1810 +({ struct rtattr *__nest = (void *)(start) + NLMSG_ALIGN((start)->rta_len); \
1811 + (start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
1812 + RTA_NEST_END(skb, __nest); \
1813 + (skb)->len; })
1815 +#define RTA_NEST_CANCEL(skb, start) \
1816 +({ if (start) \
1817 + skb_trim(skb, (unsigned char *) (start) - (skb)->data); \
1818 + -1; })
1820 +#define RTA_GET_U8(rta) \
1821 +({ if (!rta || RTA_PAYLOAD(rta) < sizeof(u8)) \
1822 + goto rtattr_failure; \
1823 + *(u8 *) RTA_DATA(rta); })
1825 +#define RTA_GET_U16(rta) \
1826 +({ if (!rta || RTA_PAYLOAD(rta) < sizeof(u16)) \
1827 + goto rtattr_failure; \
1828 + *(u16 *) RTA_DATA(rta); })
1830 +#define RTA_GET_U32(rta) \
1831 +({ if (!rta || RTA_PAYLOAD(rta) < sizeof(u32)) \
1832 + goto rtattr_failure; \
1833 + *(u32 *) RTA_DATA(rta); })
1835 +#define RTA_GET_U64(rta) \
1836 +({ u64 _tmp; \
1837 + if (!rta || RTA_PAYLOAD(rta) < sizeof(u64)) \
1838 + goto rtattr_failure; \
1839 + memcpy(&_tmp, RTA_DATA(rta), sizeof(_tmp)); \
1840 + _tmp; })
1842 +#define RTA_GET_FLAG(rta) (!!(rta))
1844 +#define RTA_GET_SECS(rta) ((unsigned long) RTA_GET_U64(rta) * HZ)
1845 +#define RTA_GET_MSECS(rta) (msecs_to_jiffies((unsigned long) RTA_GET_U64(rta)))
1847 +static inline struct rtattr *
1848 +__rta_reserve(struct sk_buff *skb, int attrtype, int attrlen)
1850 + struct rtattr *rta;
1851 + int size = RTA_LENGTH(attrlen);
1853 + rta = (struct rtattr*)skb_put(skb, RTA_ALIGN(size));
1854 + rta->rta_type = attrtype;
1855 + rta->rta_len = size;
1856 + memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size);
1857 + return rta;
1860 +#define __RTA_PUT(skb, attrtype, attrlen) \
1861 +({ if (unlikely(skb_tailroom(skb) < (int)RTA_SPACE(attrlen))) \
1862 + goto rtattr_failure; \
1863 + __rta_reserve(skb, attrtype, attrlen); })
1865 +extern void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change);
1867 +/* RTNL is used as a global lock for all changes to network configuration */
1868 +extern void rtnl_lock(void);
1869 +extern void rtnl_unlock(void);
1870 +extern int rtnl_trylock(void);
1871 +extern int rtnl_is_locked(void);
1873 +extern void rtnetlink_init(void);
1874 +extern void __rtnl_unlock(void);
1876 +#define ASSERT_RTNL() do { \
1877 + if (unlikely(!rtnl_is_locked())) { \
1878 + printk(KERN_ERR "RTNL: assertion failed at %s (%d)\n", \
1879 + __FILE__, __LINE__); \
1880 + dump_stack(); \
1881 + } \
1882 +} while(0)
1884 +#define BUG_TRAP(x) do { \
1885 + if (unlikely(!(x))) { \
1886 + printk(KERN_ERR "KERNEL: assertion (%s) failed at %s (%d)\n", \
1887 + #x, __FILE__ , __LINE__); \
1888 + } \
1889 +} while(0)
1891 +static inline u32 rtm_get_table(struct rtattr **rta, u8 table)
1893 + return RTA_GET_U32(rta[RTA_TABLE-1]);
1894 +rtattr_failure:
1895 + return table;
1898 +#endif /* __KERNEL__ */
1901 +#endif /* __LINUX_RTNETLINK_H */
1902 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/include/linux/shim.h quagga-mpls/include/linux/shim.h
1903 --- quagga/include/linux/shim.h 1969-12-31 18:00:00.000000000 -0600
1904 +++ quagga-mpls/include/linux/shim.h 2008-08-31 20:59:25.000000000 -0500
1905 @@ -0,0 +1,12 @@
1906 +#ifndef LINUX_SHIM_H
1907 +#define LINUX_SHIM_H
1909 +#define SHIMNAMSIZ 16
1910 +struct rtshim
1912 + char name[SHIMNAMSIZ+1];
1913 + short datalen;
1914 + char data[0];
1917 +#endif
1918 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/isisd/isis_zebra.c quagga-mpls/isisd/isis_zebra.c
1919 --- quagga/isisd/isis_zebra.c 2006-12-07 19:07:04.000000000 -0600
1920 +++ quagga-mpls/isisd/isis_zebra.c 2007-03-26 23:15:02.000000000 -0500
1921 @@ -337,12 +337,10 @@
1922 struct isis_route_info *route_info)
1924 struct zapi_ipv6 api;
1925 - struct in6_addr **nexthop_list;
1926 - unsigned int *ifindex_list;
1927 struct isis_nexthop6 *nexthop6;
1928 - int i, size;
1929 struct listnode *node;
1930 struct prefix_ipv6 prefix6;
1931 + int i;
1933 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
1934 return;
1935 @@ -350,35 +348,13 @@
1936 api.type = ZEBRA_ROUTE_ISIS;
1937 api.flags = 0;
1938 api.message = 0;
1939 - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
1940 - SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
1942 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
1943 api.metric = route_info->cost;
1944 #if 0
1945 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
1946 api.distance = route_info->depth;
1947 #endif
1948 - api.nexthop_num = listcount (route_info->nexthops6);
1949 - api.ifindex_num = listcount (route_info->nexthops6);
1951 - /* allocate memory for nexthop_list */
1952 - size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
1953 - nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
1954 - if (!nexthop_list)
1956 - zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
1957 - return;
1960 - /* allocate memory for ifindex_list */
1961 - size = sizeof (unsigned int) * listcount (route_info->nexthops6);
1962 - ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
1963 - if (!ifindex_list)
1965 - zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
1966 - XFREE (MTYPE_ISIS_TMP, nexthop_list);
1967 - return;
1970 /* for each nexthop */
1971 i = 0;
1972 @@ -386,21 +362,18 @@
1974 if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
1975 !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
1977 - api.nexthop_num--;
1978 - api.ifindex_num--;
1979 - continue;
1981 + continue;
1983 - nexthop_list[i] = &nexthop6->ip6;
1984 - ifindex_list[i] = nexthop6->ifindex;
1985 + SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
1986 + api.nexthop[i].type = ZEBRA_NEXTHOP_IPV6|ZEBRA_NEXTHOP_IFINDEX;
1987 + memcpy (&api.nexthop[i].gw.ipv6, &nexthop6->ip6, 16);
1988 + api.nexthop[i].intf.index = nexthop6->ifindex;
1989 i++;
1992 - api.nexthop = nexthop_list;
1993 - api.ifindex = ifindex_list;
1994 + api.nexthop_num = i;
1996 - if (api.nexthop_num && api.ifindex_num)
1997 + if (api.nexthop_num)
1999 prefix6.family = AF_INET6;
2000 prefix6.prefixlen = prefix->prefixlen;
2001 @@ -409,9 +382,6 @@
2002 SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
2005 - XFREE (MTYPE_ISIS_TMP, nexthop_list);
2006 - XFREE (MTYPE_ISIS_TMP, ifindex_list);
2008 return;
2011 @@ -420,12 +390,10 @@
2012 struct isis_route_info *route_info)
2014 struct zapi_ipv6 api;
2015 - struct in6_addr **nexthop_list;
2016 - unsigned int *ifindex_list;
2017 struct isis_nexthop6 *nexthop6;
2018 - int i, size;
2019 struct listnode *node;
2020 struct prefix_ipv6 prefix6;
2021 + int i;
2023 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
2024 return;
2025 @@ -433,29 +401,6 @@
2026 api.type = ZEBRA_ROUTE_ISIS;
2027 api.flags = 0;
2028 api.message = 0;
2029 - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
2030 - SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
2031 - api.nexthop_num = listcount (route_info->nexthops6);
2032 - api.ifindex_num = listcount (route_info->nexthops6);
2034 - /* allocate memory for nexthop_list */
2035 - size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
2036 - nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
2037 - if (!nexthop_list)
2039 - zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
2040 - return;
2043 - /* allocate memory for ifindex_list */
2044 - size = sizeof (unsigned int) * listcount (route_info->nexthops6);
2045 - ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
2046 - if (!ifindex_list)
2048 - zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
2049 - XFREE (MTYPE_ISIS_TMP, nexthop_list);
2050 - return;
2053 /* for each nexthop */
2054 i = 0;
2055 @@ -463,21 +408,16 @@
2057 if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
2058 !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
2060 - api.nexthop_num--;
2061 - api.ifindex_num--;
2062 - continue;
2064 + continue;
2066 - nexthop_list[i] = &nexthop6->ip6;
2067 - ifindex_list[i] = nexthop6->ifindex;
2068 + SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
2069 + api.nexthop[i].type = ZEBRA_NEXTHOP_IPV6|ZEBRA_NEXTHOP_IFINDEX;
2070 + memcpy (&api.nexthop[i].gw.ipv6, &nexthop6->ip6, 16);
2071 + api.nexthop[i].intf.index = nexthop6->ifindex;
2072 i++;
2075 - api.nexthop = nexthop_list;
2076 - api.ifindex = ifindex_list;
2078 - if (api.nexthop_num && api.ifindex_num)
2079 + if (api.nexthop_num)
2081 prefix6.family = AF_INET6;
2082 prefix6.prefixlen = prefix->prefixlen;
2083 @@ -485,9 +425,6 @@
2084 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, &api);
2085 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
2088 - XFREE (MTYPE_ISIS_TMP, nexthop_list);
2089 - XFREE (MTYPE_ISIS_TMP, ifindex_list);
2092 #endif /* HAVE_IPV6 */
2093 @@ -527,45 +464,29 @@
2094 isis_zebra_read_ipv4 (int command, struct zclient *zclient,
2095 zebra_size_t length)
2097 - struct stream *stream;
2098 struct zapi_ipv4 api;
2099 struct prefix_ipv4 p;
2100 unsigned long ifindex;
2101 struct in_addr nexthop;
2102 + int i;
2104 - stream = zclient->ibuf;
2105 - memset (&p, 0, sizeof (struct prefix_ipv4));
2106 - ifindex = 0;
2108 - api.type = stream_getc (stream);
2109 - api.flags = stream_getc (stream);
2110 - api.message = stream_getc (stream);
2112 - p.family = AF_INET;
2113 - p.prefixlen = stream_getc (stream);
2114 - stream_get (&p.prefix, stream, PSIZE (p.prefixlen));
2115 + zapi_ipv4_route(command, zclient, &p, &api);
2117 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
2119 - api.nexthop_num = stream_getc (stream);
2120 - nexthop.s_addr = stream_get_ipv4 (stream);
2122 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
2123 + for (i = 0; i < api.nexthop_num; i++)
2125 - api.ifindex_num = stream_getc (stream);
2126 - ifindex = stream_getl (stream);
2128 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
2129 - api.distance = stream_getc (stream);
2130 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
2131 - api.metric = stream_getl (stream);
2132 - else
2133 - api.metric = 0;
2134 + ifindex = 0;
2135 + nexthop.s_addr = 0;
2136 + if (CHECK_FLAG (api.nexthop[i].type, ZEBRA_NEXTHOP_IPV4))
2137 + nexthop.s_addr = api.nexthop[i].gw.ipv4.s_addr;
2139 - if (command == ZEBRA_IPV4_ROUTE_ADD)
2141 - if (isis->debugs & DEBUG_ZEBRA)
2142 - zlog_debug ("IPv4 Route add from Z");
2143 + if (CHECK_FLAG (api.nexthop[i].type, ZEBRA_NEXTHOP_IFINDEX))
2144 + ifindex = api.nexthop[i].intf.index;
2146 + if (command == ZEBRA_IPV4_ROUTE_ADD)
2148 + if (isis->debugs & DEBUG_ZEBRA)
2149 + zlog_debug ("IPv4 Route add from Z");
2153 return 0;
2154 @@ -576,6 +497,36 @@
2155 isis_zebra_read_ipv6 (int command, struct zclient *zclient,
2156 zebra_size_t length)
2158 + struct zapi_ipv6 api;
2159 + struct prefix_ipv6 p;
2160 + unsigned long ifindex;
2161 + struct in_addr nexthop;
2162 + int i;
2164 + zapi_ipv6_route(command, zclient, &p, &api);
2166 + /* Simply ignore link-local address. */
2167 + if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))
2168 + return 0;
2170 + for (i = 0; i < api.nexthop_num; i++)
2172 + ifindex = 0;
2173 + memset (&nexthop, 0, sizeof (struct in6_addr));
2175 + if (CHECK_FLAG (api.nexthop[i].type, ZEBRA_NEXTHOP_IPV6))
2176 + memcpy(&nexthop, &api.nexthop[i].gw.ipv6, 16);
2178 + if (CHECK_FLAG (api.nexthop[i].type, ZEBRA_NEXTHOP_IFINDEX))
2179 + ifindex = api.nexthop[i].intf.index;
2181 + if (command == ZEBRA_IPV6_ROUTE_ADD)
2183 + if (isis->debugs & DEBUG_ZEBRA)
2184 + zlog_debug ("IPv6 Route add from Z");
2188 return 0;
2190 #endif
2191 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/jleu-todo quagga-mpls/jleu-todo
2192 --- quagga/jleu-todo 1969-12-31 18:00:00.000000000 -0600
2193 +++ quagga-mpls/jleu-todo 2006-09-14 00:26:59.000000000 -0500
2194 @@ -0,0 +1,2 @@
2195 +removes path should look at NEXTHOP_FLAG_FIB (not IGNORE)
2196 +adds should look at IGNORE
2197 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/create-links quagga-mpls/ldpd/create-links
2198 --- quagga/ldpd/create-links 1969-12-31 18:00:00.000000000 -0600
2199 +++ quagga-mpls/ldpd/create-links 2006-08-09 22:02:57.000000000 -0500
2200 @@ -0,0 +1,99 @@
2201 +#!/bin/sh
2203 +DEFSRC=/home/jleu/clients/ldp-portable
2204 +if [ "x${1}" = "x" ]; then
2205 + SRC=${DEFSRC}
2206 +else
2207 + SRC=${1}
2210 +[ -d "${SRC}" ] || {
2211 + echo $"$0: directory not found: ${1}" >&2
2212 + echo $"Usage: $0 [<direcory>] (default is ${DEFSRC})" >&2
2213 + exit 1
2216 +ln -s $SRC/ldp/ldp_addr.c
2217 +ln -s $SRC/ldp/ldp_addr.h
2218 +ln -s $SRC/ldp/ldp_adj.c
2219 +ln -s $SRC/ldp/ldp_adj.h
2220 +ln -s $SRC/ldp/ldp_attr.c
2221 +ln -s $SRC/ldp/ldp_attr.h
2222 +ln -s $SRC/ldp/ldp_buf.c
2223 +ln -s $SRC/ldp/ldp_buf.h
2224 +ln -s $SRC/ldp/ldp_cfg.c
2225 +ln -s $SRC/ldp/ldp_cfg.h
2226 +ln -s $SRC/ldp/ldp_defaults.h
2227 +ln -s $SRC/ldp/ldp_entity.c
2228 +ln -s $SRC/ldp/ldp_entity.h
2229 +ln -s $SRC/ldp/ldp_fec.c
2230 +ln -s $SRC/ldp/ldp_fec.h
2231 +ln -s $SRC/ldp/ldp_global.c
2232 +ln -s $SRC/ldp/ldp_global.h
2233 +ln -s $SRC/ldp/ldp_hello.c
2234 +ln -s $SRC/ldp/ldp_hello.h
2235 +ln -s $SRC/ldp/ldp_hop.c
2236 +ln -s $SRC/ldp/ldp_hop.h
2237 +ln -s $SRC/ldp/ldp_hop_list.c
2238 +ln -s $SRC/ldp/ldp_hop_list.h
2239 +ln -s $SRC/ldp/ldp_if.c
2240 +ln -s $SRC/ldp/ldp_if.h
2241 +ln -s $SRC/ldp/ldp_inet_addr.c
2242 +ln -s $SRC/ldp/ldp_inet_addr.h
2243 +ln -s $SRC/ldp/ldp_init.c
2244 +ln -s $SRC/ldp/ldp_init.h
2245 +ln -s $SRC/ldp/ldp_inlabel.c
2246 +ln -s $SRC/ldp/ldp_inlabel.h
2247 +ln -s $SRC/ldp/ldp_keepalive.c
2248 +ln -s $SRC/ldp/ldp_keepalive.h
2249 +ln -s $SRC/ldp/ldp_label_abort.c
2250 +ln -s $SRC/ldp/ldp_label_abort.h
2251 +ln -s $SRC/ldp/ldp_label_mapping.c
2252 +ln -s $SRC/ldp/ldp_label_mapping.h
2253 +ln -s $SRC/ldp/ldp_label_rel_with.c
2254 +ln -s $SRC/ldp/ldp_label_rel_with.h
2255 +ln -s $SRC/ldp/ldp_label_request.c
2256 +ln -s $SRC/ldp/ldp_label_request.h
2257 +ln -s $SRC/ldp/ldp_mesg.c
2258 +ln -s $SRC/ldp/ldp_mesg.h
2259 +ln -s $SRC/ldp/ldp_nexthop.c
2260 +ln -s $SRC/ldp/ldp_nexthop.h
2261 +ln -s $SRC/ldp/ldp_nortel.c
2262 +ln -s $SRC/ldp/ldp_nortel.h
2263 +ln -s $SRC/ldp/ldp_notif.c
2264 +ln -s $SRC/ldp/ldp_notif.h
2265 +ln -s $SRC/ldp/ldp_outlabel.c
2266 +ln -s $SRC/ldp/ldp_outlabel.h
2267 +ln -s $SRC/ldp/ldp_pdu.h
2268 +ln -s $SRC/ldp/ldp_pdu_setup.c
2269 +ln -s $SRC/ldp/ldp_pdu_setup.h
2270 +ln -s $SRC/ldp/ldp_peer.c
2271 +ln -s $SRC/ldp/ldp_peer.h
2272 +ln -s $SRC/ldp/ldp_resource.c
2273 +ln -s $SRC/ldp/ldp_resource.h
2274 +ln -s $SRC/ldp/ldp_session.c
2275 +ln -s $SRC/ldp/ldp_session.h
2276 +ln -s $SRC/ldp/ldp_state_funcs.c
2277 +ln -s $SRC/ldp/ldp_state_machine.c
2278 +ln -s $SRC/ldp/ldp_state_machine.h
2279 +ln -s $SRC/ldp/ldp_struct.h
2280 +ln -s $SRC/ldp/ldp_tunnel.c
2281 +ln -s $SRC/ldp/ldp_tunnel.h
2283 +ln -s $SRC/common/mpls_struct.h
2284 +ln -s $SRC/common/mpls_assert.h
2285 +ln -s $SRC/common/mpls_bitfield.h
2286 +ln -s $SRC/common/mpls_fib_impl.h
2287 +ln -s $SRC/common/mpls_ifmgr_impl.h
2288 +ln -s $SRC/common/mpls_mm_impl.h
2289 +ln -s $SRC/common/mpls_mpls_impl.h
2290 +ln -s $SRC/common/mpls_policy_impl.h
2291 +ln -s $SRC/common/mpls_refcnt.h
2292 +ln -s $SRC/common/mpls_socket_impl.h
2293 +ln -s $SRC/common/mpls_timer_impl.h
2294 +ln -s $SRC/common/mpls_trace_impl.h
2295 +ln -s $SRC/common/mpls_tree_impl.h
2296 +ln -s $SRC/common/mpls_list.h
2297 +ln -s $SRC/common/mpls_lock_impl.h
2298 +ln -s $SRC/common/mpls_compare.h
2299 +ln -s $SRC/common/mpls_compare.c
2300 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/delete-links quagga-mpls/ldpd/delete-links
2301 --- quagga/ldpd/delete-links 1969-12-31 18:00:00.000000000 -0600
2302 +++ quagga-mpls/ldpd/delete-links 2006-08-09 22:02:24.000000000 -0500
2303 @@ -0,0 +1,86 @@
2304 +#!/bin/sh
2306 +rm -f ldp_addr.c
2307 +rm -f ldp_addr.h
2308 +rm -f ldp_adj.c
2309 +rm -f ldp_adj.h
2310 +rm -f ldp_attr.c
2311 +rm -f ldp_attr.h
2312 +rm -f ldp_buf.c
2313 +rm -f ldp_buf.h
2314 +rm -f ldp_cfg.c
2315 +rm -f ldp_cfg.h
2316 +rm -f ldp_defaults.h
2317 +rm -f ldp_entity.c
2318 +rm -f ldp_entity.h
2319 +rm -f ldp_fec.c
2320 +rm -f ldp_fec.h
2321 +rm -f ldp_global.c
2322 +rm -f ldp_global.h
2323 +rm -f ldp_hello.c
2324 +rm -f ldp_hello.h
2325 +rm -f ldp_hop.c
2326 +rm -f ldp_hop.h
2327 +rm -f ldp_hop_list.c
2328 +rm -f ldp_hop_list.h
2329 +rm -f ldp_if.c
2330 +rm -f ldp_if.h
2331 +rm -f ldp_inet_addr.c
2332 +rm -f ldp_inet_addr.h
2333 +rm -f ldp_init.c
2334 +rm -f ldp_init.h
2335 +rm -f ldp_inlabel.c
2336 +rm -f ldp_inlabel.h
2337 +rm -f ldp_keepalive.c
2338 +rm -f ldp_keepalive.h
2339 +rm -f ldp_label_abort.c
2340 +rm -f ldp_label_abort.h
2341 +rm -f ldp_label_mapping.c
2342 +rm -f ldp_label_mapping.h
2343 +rm -f ldp_label_rel_with.c
2344 +rm -f ldp_label_rel_with.h
2345 +rm -f ldp_label_request.c
2346 +rm -f ldp_label_request.h
2347 +rm -f ldp_mesg.c
2348 +rm -f ldp_mesg.h
2349 +rm -f ldp_nexthop.c
2350 +rm -f ldp_nexthop.h
2351 +rm -f ldp_nortel.c
2352 +rm -f ldp_nortel.h
2353 +rm -f ldp_notif.c
2354 +rm -f ldp_notif.h
2355 +rm -f ldp_outlabel.c
2356 +rm -f ldp_outlabel.h
2357 +rm -f ldp_pdu.h
2358 +rm -f ldp_pdu_setup.c
2359 +rm -f ldp_pdu_setup.h
2360 +rm -f ldp_peer.c
2361 +rm -f ldp_peer.h
2362 +rm -f ldp_resource.c
2363 +rm -f ldp_resource.h
2364 +rm -f ldp_session.c
2365 +rm -f ldp_session.h
2366 +rm -f ldp_state_funcs.c
2367 +rm -f ldp_state_machine.c
2368 +rm -f ldp_state_machine.h
2369 +rm -f ldp_struct.h
2370 +rm -f ldp_tunnel.c
2371 +rm -f ldp_tunnel.h
2373 +rm -f mpls_struct.h
2374 +rm -f mpls_assert.h
2375 +rm -f mpls_bitfield.h
2376 +rm -f mpls_fib_impl.h
2377 +rm -f mpls_ifmgr_impl.h
2378 +rm -f mpls_mm_impl.h
2379 +rm -f mpls_mpls_impl.h
2380 +rm -f mpls_policy_impl.h
2381 +rm -f mpls_refcnt.h
2382 +rm -f mpls_socket_impl.h
2383 +rm -f mpls_timer_impl.h
2384 +rm -f mpls_trace_impl.h
2385 +rm -f mpls_tree_impl.h
2386 +rm -f mpls_list.h
2387 +rm -f mpls_lock_impl.h
2388 +rm -f mpls_compare.h
2389 +rm -f mpls_compare.c
2390 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/impl_fib.c quagga-mpls/ldpd/impl_fib.c
2391 --- quagga/ldpd/impl_fib.c 1969-12-31 18:00:00.000000000 -0600
2392 +++ quagga-mpls/ldpd/impl_fib.c 2006-08-09 22:02:27.000000000 -0500
2393 @@ -0,0 +1,26 @@
2394 +#include <zebra.h>
2395 +#include "prefix.h"
2396 +#include "table.h"
2397 +#include "if.h"
2398 +#include "memory.h"
2399 +#include "vty.h"
2401 +#include "mpls_compare.h"
2403 +#include "ldp.h"
2404 +#include "ldp_struct.h"
2405 +#include "ldp_cfg.h"
2407 +#include "ldp_zebra.h"
2408 +#include "mpls_fib_impl.h"
2410 +void mpls_fib_close(mpls_fib_handle handle)
2414 +mpls_fib_handle mpls_fib_open(const mpls_instance_handle handle,
2415 + const mpls_cfg_handle cfg)
2417 + struct ldp *ldp = ldp_get();
2418 + return ldp;
2420 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/impl_fib.h quagga-mpls/ldpd/impl_fib.h
2421 --- quagga/ldpd/impl_fib.h 1969-12-31 18:00:00.000000000 -0600
2422 +++ quagga-mpls/ldpd/impl_fib.h 2006-08-09 22:02:25.000000000 -0500
2423 @@ -0,0 +1,9 @@
2424 +#ifndef LDP_IMPL_FIB_H
2425 +#define LDP_IMPL_FIB_H
2427 +#include <zebra.h>
2429 +#include "ldp_struct.h"
2430 +#include "ldp.h"
2432 +#endif
2433 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/impl_ifmgr.c quagga-mpls/ldpd/impl_ifmgr.c
2434 --- quagga/ldpd/impl_ifmgr.c 1969-12-31 18:00:00.000000000 -0600
2435 +++ quagga-mpls/ldpd/impl_ifmgr.c 2006-08-09 22:02:26.000000000 -0500
2436 @@ -0,0 +1,34 @@
2437 +#include <zebra.h>
2438 +#include "if.h"
2440 +#include "ldp.h"
2441 +#include "ldp_struct.h"
2442 +#include "mpls_ifmgr_impl.h"
2444 +static int opened = 0;
2446 +mpls_ifmgr_handle mpls_ifmgr_open(mpls_instance_handle handle,
2447 + mpls_cfg_handle cfg)
2449 + opened = 1;
2450 + return 0xdeadbeef;
2453 +void mpls_ifmgr_close(mpls_ifmgr_handle ifmgr_handle)
2455 + opened = 0;
2458 +mpls_return_enum mpls_ifmgr_get_mtu(mpls_ifmgr_handle ifmgr_handle,
2459 + mpls_if_handle if_handle, int *mtu)
2461 + *mtu = if_handle->mtu;
2462 + return MPLS_SUCCESS;
2465 +mpls_return_enum mpls_ifmgr_get_name(const mpls_ifmgr_handle handle,
2466 + const mpls_if_handle if_handle, char *name, int len)
2468 + strncpy(name, if_handle->name, len);
2469 + return MPLS_SUCCESS;
2471 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/impl_ifmgr.h quagga-mpls/ldpd/impl_ifmgr.h
2472 --- quagga/ldpd/impl_ifmgr.h 1969-12-31 18:00:00.000000000 -0600
2473 +++ quagga-mpls/ldpd/impl_ifmgr.h 2006-08-09 22:02:26.000000000 -0500
2474 @@ -0,0 +1,7 @@
2475 +#ifndef LDP_IMPL_IFMGR_H
2476 +#define LDP_IMPL_IFMGR_H
2478 +#include <zebra.h>
2479 +#include "ldp_struct.h"
2481 +#endif
2482 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/impl_lock.c quagga-mpls/ldpd/impl_lock.c
2483 --- quagga/ldpd/impl_lock.c 1969-12-31 18:00:00.000000000 -0600
2484 +++ quagga-mpls/ldpd/impl_lock.c 2006-08-09 22:02:24.000000000 -0500
2485 @@ -0,0 +1,29 @@
2486 +#include "ldp_struct.h"
2487 +#include "mpls_assert.h"
2488 +#include "mpls_mm_impl.h"
2489 +#include "mpls_lock_impl.h"
2491 +mpls_lock_handle mpls_lock_create(mpls_lock_key_type key)
2493 + int *i = mpls_malloc(sizeof(int));
2495 + *i = 0;
2496 + return i;
2499 +void mpls_lock_get(mpls_lock_handle handle)
2501 + MPLS_ASSERT(*handle == 0);
2502 + (*handle)++;
2505 +void mpls_lock_release(mpls_lock_handle handle)
2507 + MPLS_ASSERT(*handle == 1);
2508 + (*handle)--;
2511 +void mpls_lock_delete(mpls_lock_handle handle)
2513 + mpls_free(handle);
2515 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/impl_mm.c quagga-mpls/ldpd/impl_mm.c
2516 --- quagga/ldpd/impl_mm.c 1969-12-31 18:00:00.000000000 -0600
2517 +++ quagga-mpls/ldpd/impl_mm.c 2006-12-07 22:15:58.000000000 -0600
2518 @@ -0,0 +1,28 @@
2519 +#include "ldp_struct.h"
2520 +#include "mpls_mm_impl.h"
2521 +#include <stdio.h>
2522 +#include <stdlib.h>
2524 +#include "memory.h"
2526 +static int _mm_count = 0;
2528 +void *mpls_malloc(mpls_size_type size)
2530 + void *mem = XMALLOC(MTYPE_LDP, size);
2531 + if (mem) {
2532 + _mm_count++;
2534 + return mem;
2537 +void mpls_free(void *mem)
2539 + _mm_count--;
2540 + XFREE(MTYPE_LDP,mem);
2543 +void mpls_mm_results()
2545 + zlog_info("LDP MM RESULTS: %d\n", _mm_count);
2547 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/impl_mpls.c quagga-mpls/ldpd/impl_mpls.c
2548 --- quagga/ldpd/impl_mpls.c 1969-12-31 18:00:00.000000000 -0600
2549 +++ quagga-mpls/ldpd/impl_mpls.c 2008-04-03 00:32:59.000000000 -0500
2550 @@ -0,0 +1,282 @@
2551 +#include <zebra.h>
2553 +#include "stream.h"
2554 +#include "prefix.h"
2555 +#include "memory.h"
2556 +#include "log.h"
2557 +#include "zclient.h"
2558 +#include "if.h"
2560 +#include "ldp.h"
2561 +#include "ldp_struct.h"
2562 +#include "ldp_entity.h"
2563 +#include "mpls_mpls_impl.h"
2564 +#include "mpls_socket_impl.h"
2566 +#include "ldp_interface.h"
2567 +#include "impl_mpls.h"
2568 +#include "impl_fib.h"
2570 +#include "ldp_zebra.h"
2571 +#include "zclient.h"
2573 +static int label = 10000;
2574 +static int request = -2;
2575 +extern struct zclient *zclient;
2576 +extern struct list *pending_out_segment;
2577 +extern struct list *pending_ftn;
2578 +extern struct list *pending_xc;
2580 +static int new_request()
2582 + request--;
2583 + if (request > -2) {
2584 + request = -2;
2586 + return request;
2589 +mpls_mpls_handle mpls_mpls_open(mpls_instance_handle user_data)
2591 + return MPLS_SUCCESS;
2594 +void mpls_mpls_close(mpls_mpls_handle handle)
2598 +mpls_return_enum mpls_mpls_outsegment_add(mpls_mpls_handle handle, mpls_outsegment * o)
2600 + struct zapi_mpls_out_segment out;
2601 + struct interface *ifp;
2603 + memset(&out, 0, sizeof(out));
2605 + out.index = 0;
2606 + out.req = new_request();
2607 + out.owner = ZEBRA_ROUTE_LDP;
2608 + out.nh.mpls.type = ZEBRA_MPLS_LABEL_GEN;
2609 + out.nh.mpls.u.gen = o->label.u.gen;
2610 + SET_FLAG (out.nh.type, ZEBRA_NEXTHOP_MPLS);
2612 + if (o->nexthop.type & MPLS_NH_IP) {
2613 + SET_FLAG (out.nh.type, ZEBRA_NEXTHOP_IPV4);
2614 + out.nh.gw.ipv4.s_addr = htonl(o->nexthop.ip.u.ipv4);
2617 + if (o->nexthop.type & MPLS_NH_IF) {
2618 + strcpy(out.nh.intf.name, o->nexthop.if_handle->name);
2619 + SET_FLAG (out.nh.type, ZEBRA_NEXTHOP_IFNAME);
2620 + } else {
2621 + MPLS_ASSERT(o->nexthop.type & MPLS_NH_IP);
2623 + ifp = if_lookup_address(out.nh.gw.ipv4);
2624 + if (ifp) {
2625 + strcpy(out.nh.intf.name, ifp->name);
2626 + SET_FLAG (out.nh.type, ZEBRA_NEXTHOP_IFNAME);
2627 + } else {
2628 + return MPLS_FAILURE;
2632 + /* store the request number as the handle, we'll need it when the
2633 + * response from zebra arrives */
2634 + o->handle = out.req;
2636 + listnode_add(pending_out_segment, o);
2638 + zapi_mpls_out_segment_add(zclient, &out);
2639 + return MPLS_SUCCESS;
2642 +void mpls_mpls_outsegment_del(mpls_mpls_handle handle, mpls_outsegment * o)
2644 + struct zapi_mpls_out_segment out;
2645 + struct interface *ifp;
2646 + struct listnode *n;
2648 + memset(&out, 0, sizeof(out));
2650 + out.index = 0;
2651 + out.owner = ZEBRA_ROUTE_LDP;
2652 + out.nh.mpls.type = ZEBRA_MPLS_LABEL_GEN;
2653 + out.nh.mpls.u.gen = o->label.u.gen;
2654 + SET_FLAG (out.nh.type, ZEBRA_NEXTHOP_MPLS);
2656 + if (o->nexthop.type & MPLS_NH_IP) {
2657 + SET_FLAG (out.nh.type, ZEBRA_NEXTHOP_IPV4);
2658 + out.nh.gw.ipv4.s_addr = htonl(o->nexthop.ip.u.ipv4);
2661 + if (o->nexthop.type & MPLS_NH_IF) {
2662 + strncpy(out.nh.intf.name, o->nexthop.if_handle->name, INTERFACE_NAMSIZ);
2663 + SET_FLAG (out.nh.type, ZEBRA_NEXTHOP_IFNAME);
2664 + } else {
2665 + MPLS_ASSERT(o->nexthop.type & MPLS_NH_IP);
2667 + ifp = if_lookup_address(out.nh.gw.ipv4);
2668 + if (ifp) {
2669 + strcpy(out.nh.intf.name, ifp->name);
2670 + SET_FLAG (out.nh.type, ZEBRA_NEXTHOP_IFNAME);
2671 + } else {
2672 + return;
2676 + /* the out segment might still be in the pending list, remove it */
2677 + n = listnode_lookup(pending_out_segment, o);
2678 + if (n) {
2679 + list_delete_node(pending_out_segment, n);
2682 + out.index = o->handle;
2683 + zapi_mpls_out_segment_delete(zclient, &out);
2686 +mpls_return_enum mpls_mpls_insegment_add(mpls_mpls_handle handle,
2687 + mpls_insegment * i)
2689 + struct zapi_mpls_in_segment api;
2691 + if (i->label.type == MPLS_LABEL_TYPE_NONE) {
2692 + i->label.type = MPLS_LABEL_TYPE_GENERIC;
2693 + i->label.u.gen = label++;
2696 + api.owner = ZEBRA_ROUTE_LDP;
2697 + api.labelspace = i->labelspace;
2698 + api.protocol = i->family;
2699 + api.pop = i->npop;
2700 + api.label.type = ZEBRA_MPLS_LABEL_GEN;
2701 + api.label.u.gen = i->label.u.gen;
2703 + zapi_mpls_in_segment_add(zclient, &api);
2704 + return MPLS_SUCCESS;
2707 +void mpls_mpls_insegment_del(mpls_mpls_handle handle, mpls_insegment * i)
2709 + struct zapi_mpls_in_segment api;
2711 + api.owner = ZEBRA_ROUTE_LDP;
2712 + api.labelspace = i->labelspace;
2713 + api.protocol = i->family;
2714 + api.pop = i->npop;
2715 + api.label.type = ZEBRA_MPLS_LABEL_GEN;
2716 + api.label.u.gen = i->label.u.gen;
2718 + zapi_mpls_in_segment_delete(zclient, &api);
2721 +mpls_return_enum mpls_mpls_xconnect_add(mpls_mpls_handle handle, mpls_insegment * i, mpls_outsegment * o)
2723 + struct zapi_mpls_xc api;
2724 + struct listnode *n;
2726 + n = listnode_lookup(pending_out_segment, o);
2727 + if (n) {
2728 + struct pending_xc_data *x = XMALLOC(MTYPE_TMP,
2729 + sizeof(struct pending_xc_data));
2730 + x->o = o;
2731 + x->i = i;
2732 + x->h = handle;
2733 + listnode_add(pending_xc, x);
2734 + return MPLS_SUCCESS;
2737 + api.owner = ZEBRA_ROUTE_LDP;
2738 + api.in_labelspace = i->labelspace;
2739 + api.in_label.type = ZEBRA_MPLS_LABEL_GEN;
2740 + api.in_label.u.gen = i->label.u.gen;
2741 + api.out_index = o->handle;
2743 + zapi_mpls_xc_add(zclient, &api);
2744 + return MPLS_SUCCESS;
2747 +void mpls_mpls_xconnect_del(mpls_mpls_handle handle, mpls_insegment * i,
2748 + mpls_outsegment * o)
2750 + struct zapi_mpls_xc api;
2751 + struct listnode *n;
2753 + /* if its in the pending XC list, no need to send the delete because
2754 + * the add was never sent
2755 + */
2756 + n = listnode_lookup(pending_xc, o);
2757 + if (n) {
2758 + list_delete_node(pending_xc, n);
2759 + return;
2762 + api.owner = ZEBRA_ROUTE_LDP;
2763 + api.in_labelspace = i->labelspace;
2764 + api.in_label.type = ZEBRA_MPLS_LABEL_GEN;
2765 + api.in_label.u.gen = i->label.u.gen;
2766 + api.out_index = o->handle;
2768 + zapi_mpls_xc_delete(zclient, &api);
2771 +mpls_return_enum mpls_mpls_fec2out_add(mpls_mpls_handle handle, mpls_fec * f,
2772 + mpls_outsegment * o)
2774 + struct zapi_mpls_ftn api;
2775 + struct listnode *n;
2776 + int retval;
2778 + n = listnode_lookup(pending_out_segment, o);
2779 + if (n) {
2780 + struct pending_ftn_data *fn = XMALLOC(MTYPE_TMP,
2781 + sizeof(struct pending_ftn_data));
2782 + fn->o = o;
2783 + fn->f = f;
2784 + fn->h = handle;
2785 + listnode_add(pending_ftn, fn);
2786 + return MPLS_SUCCESS;
2789 + api.fec.type = ZEBRA_MPLS_FEC_IPV4;
2790 + mpls_fec2zebra_prefix(f,&api.fec.u.p);
2791 + api.out_index = o->handle;
2792 + api.fec.owner = -1;
2793 + api.owner = ZEBRA_ROUTE_LDP;
2795 + retval = zapi_mpls_ftn_add(zclient, &api);
2796 + return MPLS_SUCCESS;
2799 +void mpls_mpls_fec2out_del(mpls_mpls_handle handle, mpls_fec * f,
2800 + mpls_outsegment * o)
2802 + struct zapi_mpls_ftn api;
2803 + struct listnode *n;
2804 + int retval;
2806 + /* if its in the pending FTN list, no need to send the delete because
2807 + * the add was never sent
2808 + */
2809 + n = listnode_lookup(pending_ftn, o);
2810 + if (n) {
2811 + list_delete_node(pending_ftn, n);
2812 + return;
2815 + api.fec.type = ZEBRA_MPLS_FEC_IPV4;
2816 + mpls_fec2zebra_prefix(f,&api.fec.u.p);
2817 + api.out_index = o->handle;
2818 + api.fec.owner = -1;
2819 + api.owner = ZEBRA_ROUTE_LDP;
2821 + retval = zapi_mpls_ftn_delete(zclient, &api);
2824 +mpls_return_enum mpls_mpls_get_label_space_range(mpls_mpls_handle handle,
2825 + mpls_range * r)
2827 + r->type = MPLS_LABEL_RANGE_GENERIC;
2828 + r->min.u.gen = 16;
2829 + r->max.u.gen = 0xFFFFF;
2831 + return MPLS_SUCCESS;
2833 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/impl_mpls.h quagga-mpls/ldpd/impl_mpls.h
2834 --- quagga/ldpd/impl_mpls.h 1969-12-31 18:00:00.000000000 -0600
2835 +++ quagga-mpls/ldpd/impl_mpls.h 2006-08-09 22:02:26.000000000 -0500
2836 @@ -0,0 +1,22 @@
2837 +#ifndef IMPL_MPLS_H
2838 +#define IMPL_MPLS_H
2840 +#include "ldp_interface.h"
2842 +struct pending_ftn_data
2844 + mpls_mpls_handle h;
2845 + mpls_outsegment *o;
2846 + mpls_fec *f;
2849 +struct pending_xc_data
2851 + mpls_mpls_handle h;
2852 + mpls_outsegment *o;
2853 + mpls_insegment *i;
2856 +int do_mpls_labelspace(struct ldp_interface *li);
2858 +#endif
2859 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/impl_policy.c quagga-mpls/ldpd/impl_policy.c
2860 --- quagga/ldpd/impl_policy.c 1969-12-31 18:00:00.000000000 -0600
2861 +++ quagga-mpls/ldpd/impl_policy.c 2006-10-02 20:48:44.000000000 -0500
2862 @@ -0,0 +1,85 @@
2863 +#include <zebra.h>
2865 +#include "ldp_struct.h"
2866 +#include "ldp_interface.h"
2867 +#include "ldp_zebra.h"
2868 +#include "mpls_policy_impl.h"
2869 +#include "ldp.h"
2871 +mpls_bool mpls_policy_import_check(mpls_instance_handle handle, mpls_fec * f,
2872 + mpls_nexthop * nh)
2874 + return MPLS_BOOL_TRUE;
2877 +mpls_bool mpls_policy_ingress_check(mpls_instance_handle handle, mpls_fec * f, mpls_nexthop * nh)
2879 + return MPLS_BOOL_TRUE;
2882 +mpls_bool mpls_policy_egress_check(mpls_instance_handle handle, mpls_fec * fec,
2883 + mpls_nexthop *nexthop)
2885 + struct ldp *ldp = handle;
2886 + int result = MPLS_BOOL_FALSE;
2887 + struct prefix p;
2889 + switch(ldp->egress) {
2890 + case LDP_EGRESS_ALL:
2892 + result = MPLS_BOOL_TRUE;
2893 + break;
2895 + case LDP_EGRESS_LSRID:
2897 + mpls_fec2zebra_prefix(fec,&p);
2898 + if (prefix_same(&router_id, &p)) {
2899 + result = MPLS_BOOL_TRUE;
2901 + break;
2903 + case LDP_EGRESS_CONNECTED:
2905 + if (nexthop->attached == MPLS_BOOL_TRUE) {
2906 + result = MPLS_BOOL_TRUE;
2908 + break;
2910 + default:
2911 + break;
2913 + return result;
2916 +mpls_bool mpls_policy_export_check(mpls_instance_handle handle, mpls_fec * f, mpls_nexthop * nh)
2918 + return MPLS_BOOL_TRUE;
2921 +mpls_bool mpls_policy_address_export_check(mpls_instance_handle handle,
2922 + mpls_inet_addr *addr) {
2923 + struct ldp *ldp = handle;
2924 + mpls_bool flag = MPLS_BOOL_FALSE;
2925 + struct interface *ifp;
2926 + struct in_addr in;
2928 + in.s_addr = htonl(addr->u.ipv4);
2930 + switch (ldp->address) {
2931 + case LDP_ADDRESS_LDP:
2932 + if ((ifp = if_lookup_exact_address(in)) &&
2933 + (struct ldp_interface*)(ifp->info)) {
2934 + flag = MPLS_BOOL_TRUE;
2936 + /* fall through */
2937 + case LDP_ADDRESS_LSRID:
2938 + if (in.s_addr == router_id.u.prefix4.s_addr) {
2939 + flag = MPLS_BOOL_TRUE;
2941 + break;
2942 + case LDP_ADDRESS_ALL:
2943 + flag = MPLS_BOOL_TRUE;
2944 + break;
2946 + return flag;
2948 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/impl_socket.c quagga-mpls/ldpd/impl_socket.c
2949 --- quagga/ldpd/impl_socket.c 1969-12-31 18:00:00.000000000 -0600
2950 +++ quagga-mpls/ldpd/impl_socket.c 2006-11-22 00:37:10.000000000 -0600
2951 @@ -0,0 +1,659 @@
2952 +#include <stdio.h>
2953 +#include <unistd.h>
2955 +#include <zebra.h>
2956 +#include "thread.h"
2957 +#include "sockopt.h"
2958 +#include "privs.h"
2959 +#include "log.h"
2961 +#include "ldp.h"
2963 +#include "ldp_struct.h"
2964 +#include "ldp_state_machine.h"
2965 +#include "mpls_mm_impl.h"
2966 +#include "mpls_socket_impl.h"
2969 +extern struct thread_master *master;
2970 +extern struct zebra_privs_t ldpd_privs;
2972 +struct mpls_socket {
2973 + int fd;
2974 + int type;
2975 + struct thread *read;
2976 + struct thread *write;
2977 + void *extra;
2980 +static void _sockaddr2mpls_dest(const struct sockaddr *addr, mpls_dest * dest)
2982 + dest->addr.type = MPLS_FAMILY_IPV4;
2983 + switch (dest->addr.type) {
2984 + case MPLS_FAMILY_IPV4:
2985 + dest->port = ntohs(((const struct sockaddr_in *)addr)->sin_port);
2986 + dest->addr.u.ipv4 = ntohl(((const struct sockaddr_in *)addr)->sin_addr.s_addr);
2987 + break;
2988 + default:
2989 + assert(0);
2993 +static void _mpls_dest2sockaddr(const mpls_dest * dest, struct sockaddr *addr)
2995 + memset(addr, 0, sizeof(struct sockaddr));
2997 + switch (dest->addr.type) {
2998 + case MPLS_FAMILY_IPV4:
3000 + addr->sa_family = AF_INET;
3001 + ((struct sockaddr_in *)addr)->sin_port = htons(dest->port);
3002 + ((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(dest->addr.u.ipv4);
3003 + break;
3005 + default:
3007 + assert(0);
3012 +static int mplsd_read(struct thread *thread) {
3013 + int retval;
3014 + struct ldp *ldp = ldp_get();
3015 + mpls_socket_handle socket;
3017 + MPLS_ASSERT(thread);
3019 + socket = THREAD_ARG(thread);
3020 + socket->read = thread_add_read(master,mplsd_read,socket,socket->fd);
3022 + if (!ldp) {
3023 + return 0;
3026 + switch (socket->type) {
3027 + case MPLS_SOCKET_TCP_DATA:
3029 + retval = ldp_event(ldp->h, socket, socket->extra,
3030 + LDP_EVENT_TCP_DATA);
3031 + break;
3033 + case MPLS_SOCKET_TCP_LISTEN:
3035 + retval = ldp_event(ldp->h, socket, socket->extra,
3036 + LDP_EVENT_TCP_LISTEN);
3037 + break;
3039 + case MPLS_SOCKET_UDP_DATA:
3041 + retval = ldp_event(ldp->h, socket, socket->extra,
3042 + LDP_EVENT_UDP_DATA);
3043 + break;
3045 + default:
3047 + assert(0);
3050 + return 0;
3053 +static int mplsd_write(struct thread *thread) {
3054 + struct ldp *ldp = ldp_get();
3055 + int retval;
3056 + mpls_socket_handle socket;
3058 + MPLS_ASSERT(thread);
3060 + socket = THREAD_ARG(thread);
3061 + socket->write = thread_add_write(master,mplsd_write,socket,socket->fd);
3062 + if (socket->type != MPLS_SOCKET_TCP_CONNECT) {
3063 + assert(0);
3065 + retval = ldp_event(ldp->h, socket, socket->extra,
3066 + LDP_EVENT_TCP_CONNECT);
3068 + return 0;
3071 +mpls_socket_mgr_handle mpls_socket_mgr_open(mpls_instance_handle user_data)
3073 + return 0xdeadbeef;
3076 +void mpls_socket_mgr_close(mpls_socket_mgr_handle handle)
3080 +void mpls_socket_close(mpls_socket_mgr_handle handle, mpls_socket_handle socket)
3082 + if (socket) {
3083 + close(socket->fd);
3084 + mpls_free(socket);
3088 +mpls_socket_handle mpls_socket_create_tcp(mpls_socket_mgr_handle handle)
3090 + struct mpls_socket *sock;
3091 + sock = mpls_malloc(sizeof(struct mpls_socket));
3092 + memset(sock,0,sizeof(struct mpls_socket));
3093 + sock->fd = socket(AF_INET, SOCK_STREAM, 0);
3094 + MPLS_ASSERT(sock->fd > -1);
3095 + return sock;
3098 +mpls_socket_handle mpls_socket_create_udp(mpls_socket_mgr_handle handle)
3100 + struct mpls_socket *sock;
3101 + u_char one = 1;
3103 + sock = mpls_malloc(sizeof(struct mpls_socket));
3104 + memset(sock,0,sizeof(struct mpls_socket));
3105 + sock->fd = socket(AF_INET, SOCK_DGRAM, 0);
3106 + MPLS_ASSERT(sock->fd > -1);
3107 + if (setsockopt(sock->fd,SOL_IP,IP_PKTINFO,&one,sizeof(one)) < 0) {
3108 + perror("PKTINFO");
3109 + mpls_free(sock);
3110 + return NULL;
3112 + return sock;
3115 +mpls_socket_handle mpls_socket_create_raw(mpls_socket_mgr_handle handle,
3116 + int proto)
3118 + struct mpls_socket *sock;
3119 + u_char one = 1;
3121 + sock = mpls_malloc(sizeof(struct mpls_socket));
3122 + memset(sock,0,sizeof(struct mpls_socket));
3124 + if (ldpd_privs.change(ZPRIVS_RAISE))
3125 + zlog (NULL, LOG_ERR, "Can't raise privileges");
3127 + sock->fd = socket(AF_INET, SOCK_RAW, proto);
3128 + MPLS_ASSERT(sock->fd > -1);
3129 + if (setsockopt(sock->fd,SOL_IP,IP_PKTINFO,&one,sizeof(one)) < 0) {
3130 + perror("PKTINFO");
3131 + mpls_free(sock);
3132 + sock = NULL;
3135 + if (ldpd_privs.change(ZPRIVS_LOWER))
3136 + zlog (NULL, LOG_ERR, "Can't lower privileges");
3138 + return sock;
3141 +mpls_socket_handle mpls_socket_tcp_accept(mpls_socket_mgr_handle handle,
3142 + mpls_socket_handle socket, mpls_dest * from)
3144 + struct mpls_socket *sock = mpls_malloc(sizeof(struct mpls_socket));
3145 + struct sockaddr addr;
3146 + unsigned int size = sizeof(addr);
3148 + if ((sock->fd = accept(socket->fd,&addr,&size)) < 0) {
3149 + return NULL;
3152 + _sockaddr2mpls_dest(&addr, from);
3153 + return sock;
3156 +mpls_return_enum mpls_socket_bind(mpls_socket_mgr_handle handle,
3157 + mpls_socket_handle socket, const mpls_dest * local)
3159 + struct sockaddr addr;
3160 + int result = MPLS_SUCCESS;
3162 + _mpls_dest2sockaddr(local, &addr);
3164 + if (ldpd_privs.change(ZPRIVS_RAISE))
3165 + zlog (NULL, LOG_ERR, "Can't raise privileges");
3167 + if (bind(socket->fd, &addr, sizeof(struct sockaddr_in)) < 0) {
3168 + perror("bind");
3169 + result = MPLS_FAILURE;
3172 + if (ldpd_privs.change(ZPRIVS_LOWER))
3173 + zlog (NULL, LOG_ERR, "Can't lower privileges");
3175 + return result;
3178 +mpls_return_enum mpls_socket_tcp_listen(mpls_socket_mgr_handle handle,
3179 + mpls_socket_handle socket, int depth)
3181 + if (listen(socket->fd, depth) < 0) {
3182 + return MPLS_FAILURE;
3184 + return MPLS_SUCCESS;
3187 +mpls_return_enum mpls_socket_tcp_connect(mpls_socket_mgr_handle handle,
3188 + mpls_socket_handle socket, const mpls_dest * to)
3190 + struct sockaddr addr, *iaddr = NULL;
3192 + if (to != NULL) {
3193 + _mpls_dest2sockaddr(to, &addr);
3194 + iaddr = &addr;
3195 + } else {
3196 + iaddr = NULL;
3199 + if (connect(socket->fd, iaddr, sizeof(struct sockaddr)) < 0) {
3200 + if (errno == EINPROGRESS) {
3201 + return MPLS_NON_BLOCKING;
3204 + if (errno == EALREADY) {
3205 + return MPLS_SUCCESS;
3207 + perror("connect");
3208 + return MPLS_FAILURE;
3210 + return MPLS_SUCCESS;
3213 +mpls_return_enum mpls_socket_connect_status(mpls_socket_mgr_handle handle,
3214 + mpls_socket_handle socket)
3216 + unsigned int size = sizeof(int);
3217 + int num = 1;
3219 + if (getsockopt(socket->fd, SOL_SOCKET, SO_ERROR, &num, &size) < 0) {
3220 + perror("getsockopt");
3221 + return MPLS_FAILURE;
3223 + if (!num) {
3224 + return MPLS_SUCCESS;
3226 + perror("getsockopt");
3227 + return MPLS_NON_BLOCKING;
3230 +int mpls_socket_get_errno(const mpls_socket_mgr_handle handle,
3231 + mpls_socket_handle socket)
3233 + return errno;
3236 +mpls_return_enum mpls_socket_options(mpls_socket_mgr_handle handle,
3237 + mpls_socket_handle socket, uint32_t flag)
3239 + mpls_return_enum retval = MPLS_SUCCESS;
3240 + int one = 1;
3242 + if (ldpd_privs.change(ZPRIVS_RAISE))
3243 + zlog (NULL, LOG_ERR, "Can't raise privileges");
3245 + if (flag & MPLS_SOCKOP_REUSE) {
3246 + if (setsockopt(socket->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one,
3247 + sizeof(one)) < 0) {
3248 + retval = MPLS_FAILURE;
3249 + goto mpls_socket_options_exit;
3252 + if (flag & MPLS_SOCKOP_NONBLOCK) {
3253 + if (fcntl(socket->fd, F_SETFL, O_NONBLOCK) < 0) {
3254 + retval = MPLS_FAILURE;
3255 + goto mpls_socket_options_exit;
3258 + if (flag & MPLS_SOCKOP_ROUTERALERT) {
3259 + if (setsockopt(socket->fd, SOL_IP, IP_ROUTER_ALERT, (char *)&one,
3260 + sizeof(one)) < 0) {
3261 + retval = MPLS_FAILURE;
3262 + goto mpls_socket_options_exit;
3265 + if (flag & MPLS_SOCKOP_HDRINCL) {
3266 + if (setsockopt(socket->fd, SOL_IP, IP_HDRINCL, (char *)&one,
3267 + sizeof(one)) < 0) {
3268 + retval = MPLS_FAILURE;
3272 +mpls_socket_options_exit:
3274 + if (ldpd_privs.change(ZPRIVS_LOWER))
3275 + zlog (NULL, LOG_ERR, "Can't lower privileges");
3277 + return retval;
3280 +mpls_return_enum mpls_socket_multicast_options(mpls_socket_mgr_handle handle,
3281 + mpls_socket_handle socket, int ttl, int loop)
3283 + mpls_return_enum retval = MPLS_SUCCESS;
3284 + int zero = loop;
3285 + int one = ttl;
3287 + if (ldpd_privs.change(ZPRIVS_RAISE))
3288 + zlog (NULL, LOG_ERR, "Can't raise privileges");
3290 + if (setsockopt(socket->fd,SOL_IP,IP_MULTICAST_TTL,&one,sizeof(one))<0) {
3291 + retval = MPLS_FAILURE;
3292 + goto mpls_socket_multicast_options_exit;
3295 + if (setsockopt(socket->fd,SOL_IP,IP_MULTICAST_LOOP,&zero,sizeof(zero))<0) {
3296 + retval = MPLS_FAILURE;
3299 +mpls_socket_multicast_options_exit:
3300 + if (ldpd_privs.change(ZPRIVS_LOWER))
3301 + zlog (NULL, LOG_ERR, "Can't lower privileges");
3303 + return retval;
3306 +mpls_return_enum mpls_socket_multicast_if_tx(mpls_socket_mgr_handle handle,
3307 + mpls_socket_handle socket, const ldp_if * iff)
3309 + mpls_return_enum retval = MPLS_SUCCESS;
3310 + struct in_addr addr;
3311 + unsigned int ifindex = 0;
3312 + addr.s_addr = 0;
3314 + if (ldpd_privs.change(ZPRIVS_RAISE))
3315 + zlog (NULL, LOG_ERR, "Can't raise privileges");
3317 + if (iff == NULL) {
3318 + addr.s_addr = ntohl(INADDR_ANY);
3319 + } else {
3320 + ifindex = iff->handle->ifindex;
3323 + if (setsockopt_multicast_ipv4(socket->fd,IP_MULTICAST_IF,addr,0,ifindex)<0) {
3324 + retval = MPLS_FAILURE;
3327 + if (ldpd_privs.change(ZPRIVS_LOWER))
3328 + zlog (NULL, LOG_ERR, "Can't lower privileges");
3330 + return retval;
3333 +mpls_return_enum mpls_socket_multicast_if_join(mpls_socket_mgr_handle handle,
3334 + mpls_socket_handle socket, const ldp_if * iff, const mpls_inet_addr * mult)
3336 + mpls_return_enum retval = MPLS_SUCCESS;
3337 + struct in_addr addr;
3338 + unsigned int ifindex = 0;
3339 + addr.s_addr = 0;
3341 + if (ldpd_privs.change(ZPRIVS_RAISE))
3342 + zlog (NULL, LOG_ERR, "Can't raise privileges");
3344 + if (iff == NULL) {
3345 + addr.s_addr = ntohl(INADDR_ANY);
3346 + } else {
3347 + ifindex = iff->handle->ifindex;
3350 + if (setsockopt_multicast_ipv4(socket->fd,IP_ADD_MEMBERSHIP,addr,
3351 + htonl(mult->u.ipv4),ifindex)<0) {
3352 + retval = MPLS_FAILURE;
3355 + if (ldpd_privs.change(ZPRIVS_LOWER))
3356 + zlog (NULL, LOG_ERR, "Can't lower privileges");
3358 + return retval;
3361 +void mpls_socket_multicast_if_drop(mpls_socket_mgr_handle handle,
3362 + mpls_socket_handle socket, const ldp_if * iff, const mpls_inet_addr * mult)
3364 + struct in_addr addr;
3365 + unsigned int ifindex = 0;
3366 + addr.s_addr = 0;
3368 + if (ldpd_privs.change(ZPRIVS_RAISE))
3369 + zlog (NULL, LOG_ERR, "Can't raise privileges");
3371 + if (iff == NULL) {
3372 + addr.s_addr = ntohl(INADDR_ANY);
3373 + } else {
3374 + ifindex = iff->handle->ifindex;
3377 + if (setsockopt_multicast_ipv4(socket->fd,IP_DROP_MEMBERSHIP,addr,
3378 + htonl(mult->u.ipv4),ifindex)<0) {
3379 + perror("multicast drop membership");
3382 + if (ldpd_privs.change(ZPRIVS_LOWER))
3383 + zlog (NULL, LOG_ERR, "Can't lower privileges");
3385 + return;
3388 +mpls_return_enum mpls_socket_readlist_add(mpls_socket_mgr_handle handle,
3389 + mpls_socket_handle socket, void *extra, mpls_socket_enum type)
3391 + socket->type = type;
3392 + socket->extra = extra;
3393 + MPLS_ASSERT(socket && (socket->fd > -1));
3394 + socket->read = thread_add_read(master,mplsd_read,socket,socket->fd);
3395 + MPLS_ASSERT(socket->read);
3396 + return MPLS_SUCCESS;
3399 +void mpls_socket_readlist_del(mpls_socket_mgr_handle handle,
3400 + mpls_socket_handle socket)
3402 + if (socket && socket->read) {
3403 + thread_cancel(socket->read);
3404 + socket->read = NULL;
3408 +mpls_return_enum mpls_socket_writelist_add(mpls_socket_mgr_handle handle,
3409 + mpls_socket_handle socket, void *extra, mpls_socket_enum type)
3411 + socket->type = type;
3412 + socket->extra = extra;
3413 + MPLS_ASSERT(socket && (socket->fd > -1));
3414 + socket->write = thread_add_write(master,mplsd_write,socket,socket->fd);
3415 + MPLS_ASSERT(socket->write);
3416 + return MPLS_SUCCESS;
3419 +void mpls_socket_writelist_del(mpls_socket_mgr_handle handle,
3420 + mpls_socket_handle socket)
3422 + if (socket) {
3423 + thread_cancel(socket->write);
3424 + socket->write = NULL;
3428 +int mpls_socket_tcp_read(mpls_socket_mgr_handle handle,
3429 + mpls_socket_handle socket,
3430 + uint8_t * buffer, int size)
3432 + int ret = read(socket->fd,buffer,size);
3433 + if (ret < 0 && errno != EAGAIN) {
3434 + perror("mpls_socket_tcp_read");
3435 + return 0;
3437 + return ret;
3440 +int mpls_socket_tcp_write(mpls_socket_mgr_handle handle,
3441 + mpls_socket_handle socket,
3442 + uint8_t * buffer, int size)
3444 + return write(socket->fd,buffer,size);
3447 +int mpls_socket_udp_sendto(mpls_socket_mgr_handle handle,
3448 + mpls_socket_handle socket, uint8_t * buffer, int size, const mpls_dest * to)
3450 + struct sockaddr addr;
3451 + int retval;
3453 + _mpls_dest2sockaddr(to, &addr);
3455 + retval = sendto(socket->fd,buffer,size,0,&addr,sizeof(struct sockaddr));
3457 + return retval;
3460 +int mpls_socket_udp_recvfrom(mpls_socket_mgr_handle handle,
3461 + mpls_socket_handle socket, uint8_t * buffer, int size, mpls_dest * from)
3463 + int ret;
3464 + unsigned int ifindex = 0;
3465 + struct iovec iov;
3466 + struct cmsghdr *cmsg;
3467 + struct in_pktinfo *pktinfo;
3468 + struct sockaddr addr;
3469 + char buff [sizeof (*cmsg) + sizeof (*pktinfo)];
3470 + struct msghdr msgh = {&addr, sizeof(struct sockaddr), &iov, 1, buff,
3471 + sizeof (*cmsg) + sizeof (*pktinfo), 0};
3473 + iov.iov_base = buffer;
3474 + iov.iov_len = size;
3475 + ret = recvmsg(socket->fd,&msgh,0);
3477 + if (ret < 0 && errno != EAGAIN) {
3478 + return 0;
3481 + cmsg = CMSG_FIRSTHDR(&msgh);
3483 + if (cmsg != NULL &&
3484 + cmsg->cmsg_level == IPPROTO_IP &&
3485 + cmsg->cmsg_type == IP_PKTINFO) {
3486 + pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg);
3487 + ifindex = pktinfo->ipi_ifindex;
3488 + from->if_handle = if_lookup_by_index(ifindex);
3489 + _sockaddr2mpls_dest((const struct sockaddr*)&addr, from);
3492 + return ret;
3495 +mpls_return_enum mpls_socket_get_local_name(mpls_socket_mgr_handle handle,
3496 + mpls_socket_handle socket, mpls_dest *name) {
3497 + struct sockaddr_in address;
3498 + char inode_str[32];
3499 + char fd_str[20];
3500 + int inode_num;
3501 + FILE *file = NULL;
3502 + char line[256];
3503 + int ret = 1;
3504 + int uid;
3505 + int euid;
3507 + /* the only way on linux to get the source address used for a TCP session
3508 + * is to find the 'inode of the socket' by looking at what
3509 + * /proc/self/fd/<socket fd> points to (symlink). Using readlink() we
3510 + * can get the 'path' of the inode (something like 'socket:[<inode>]').
3511 + * We can then use that inode to find the TCP session info for the socket
3512 + * in /proc/net/tcp
3514 + * The local address of the socket is the 2nd column, the inode number is
3515 + * in the 14th column
3517 + * Since the sockets we create are done under 'CAP_NET_ADMIN' their
3518 + * entries in /proc/self/fd/ are all chmod 700, chown root.root. So we
3519 + * cannot see what they point to without elevating our permissions.
3520 + * By using CAP_SETID we can issue a setuid(0) and seteuid(0) which
3521 + * allows us to read the files owned by root.
3522 + */
3524 + memset(inode_str, 0, sizeof(inode_str));
3525 + sprintf(fd_str, "/proc/self/fd/%d", socket->fd);
3527 + uid = getuid();
3528 + euid = geteuid();
3530 + if (ldpd_privs.change(ZPRIVS_RAISE))
3531 + zlog (NULL, LOG_ERR, "Can't raise privileges");
3533 + setuid(0);
3534 + seteuid(0);
3536 + ret = readlink(fd_str, inode_str, sizeof(inode_str));
3538 + setuid(uid);
3539 + seteuid(euid);
3541 + if (ldpd_privs.change(ZPRIVS_LOWER))
3542 + zlog (NULL, LOG_ERR, "Can't lower privileges");
3544 + if (ret <= 0)
3545 + goto mpls_socket_get_local_name_exit;
3547 + ret = sscanf(inode_str,"socket:[%d]", &inode_num);
3548 + if (ret != 1) {
3549 + ret = 1;
3550 + goto mpls_socket_get_local_name_exit;
3553 + file = fopen("/proc/net/tcp","r");
3554 + if (file == NULL)
3555 + goto mpls_socket_get_local_name_exit;
3557 + /* skip header */
3558 + fgets(line, sizeof(line), file);
3560 + while(!feof(file)) {
3561 + if (fgets(line, sizeof(line), file)) {
3562 + unsigned long rxq, txq, time_len, retr, inode;
3563 + int num, local_port, rem_port, d, state, uid, timer_run, timeout;
3564 + char rem_addr[128], local_addr[128], timers[64], buffer[1024], more[512];
3566 + num = sscanf(line,
3567 + "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %ld %512s\n",
3568 + &d, local_addr, &local_port, rem_addr, &rem_port, &state,
3569 + &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more);
3571 + if (num < 13)
3572 + break;
3574 + if (inode == inode_num) {
3575 + sscanf(local_addr, "%X", &address.sin_addr.s_addr);
3576 + address.sin_family = AF_INET;
3577 + address.sin_port = local_port;
3578 + ret = 0;
3579 + break;
3584 +mpls_socket_get_local_name_exit:
3586 + if (file)
3587 + fclose(file);
3589 + if (ret) {
3590 + memset(name, 0, sizeof(mpls_dest));
3591 + return MPLS_FAILURE;
3593 + _sockaddr2mpls_dest((struct sockaddr*)&address, name);
3594 + return MPLS_SUCCESS;
3597 +mpls_return_enum mpls_socket_get_remote_name(mpls_socket_mgr_handle handle,
3598 + mpls_socket_handle socket, mpls_dest *name) {
3599 + struct sockaddr address;
3600 + int size = sizeof(address);
3601 + int ret;
3603 + ret = getpeername(socket->fd, &address, &size);
3604 + if (ret) {
3605 + memset(name, 0, sizeof(mpls_dest));
3606 + return MPLS_FAILURE;
3608 + _sockaddr2mpls_dest(&address, name);
3609 + return MPLS_SUCCESS;
3611 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/impl_timer.c quagga-mpls/ldpd/impl_timer.c
3612 --- quagga/ldpd/impl_timer.c 1969-12-31 18:00:00.000000000 -0600
3613 +++ quagga-mpls/ldpd/impl_timer.c 2006-08-09 22:02:24.000000000 -0500
3614 @@ -0,0 +1,93 @@
3615 +#include "ldp_struct.h"
3616 +#include "mpls_timer_impl.h"
3617 +#include "mpls_mm_impl.h"
3619 +#include "thread.h"
3621 +struct mpls_timer {
3622 + struct thread *timer;
3623 + mpls_time_unit_enum unit;
3624 + int duration;
3625 + int type;
3626 + void *extra;
3627 + mpls_cfg_handle g;
3628 + void (*callback) (mpls_timer_handle timer, void *extra, mpls_cfg_handle g);
3629 + int active;
3632 +extern struct thread_master *master;
3634 +int mpls_timer(struct thread* thread) {
3635 + mpls_timer_handle timer = THREAD_ARG(thread);
3637 + timer->active = 0;
3638 + if (timer->type == MPLS_TIMER_REOCCURRING) {
3639 + timer->timer = thread_add_timer(master,mpls_timer,timer,timer->duration);
3640 + timer->active = 1;
3642 + timer->callback(timer,timer->extra,timer->g);
3644 + return 0;
3647 +mpls_timer_mgr_handle mpls_timer_open(mpls_instance_handle user_data)
3649 + return 0xdeadbeef;
3652 +void mpls_timer_close(mpls_timer_mgr_handle handle)
3656 +mpls_timer_handle mpls_timer_create(mpls_timer_mgr_handle handle,
3657 + mpls_time_unit_enum unit, int duration, void *extra, mpls_cfg_handle g,
3658 + void (*callback) (mpls_timer_handle timer, void *extra, mpls_cfg_handle g))
3660 + struct mpls_timer *timer;
3661 + timer = mpls_malloc(sizeof(struct mpls_timer));
3662 + timer->unit = unit;
3663 + timer->duration = duration;
3664 + timer->extra = extra;
3665 + timer->g = g;
3666 + timer->callback = callback;
3667 + timer->active = 0;
3669 + return timer;
3672 +mpls_return_enum mpls_timer_modify(mpls_timer_mgr_handle handle,
3673 + mpls_timer_handle timer, int duration)
3675 + if (!timer) {
3676 + return MPLS_FAILURE;
3678 + timer->duration = duration;
3679 + return MPLS_SUCCESS;
3682 +void mpls_timer_delete(mpls_timer_mgr_handle handle, mpls_timer_handle timer)
3684 + if (timer) {
3685 + mpls_free(timer);
3689 +mpls_return_enum mpls_timer_start(mpls_timer_mgr_handle handle,
3690 + mpls_timer_handle timer, mpls_timer_type_enum type)
3692 + if (!timer) {
3693 + return MPLS_FAILURE;
3695 + timer->type = type;
3696 + timer->timer = thread_add_timer(master,mpls_timer,timer,timer->duration);
3697 + timer->active = 1;
3698 + return MPLS_SUCCESS;
3701 +void mpls_timer_stop(mpls_timer_mgr_handle handle, mpls_timer_handle timer)
3703 + if (timer && timer->active) {
3704 + thread_cancel(timer->timer);
3705 + timer->timer = NULL;
3708 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/impl_tree.c quagga-mpls/ldpd/impl_tree.c
3709 --- quagga/ldpd/impl_tree.c 1969-12-31 18:00:00.000000000 -0600
3710 +++ quagga-mpls/ldpd/impl_tree.c 2006-11-08 22:18:53.000000000 -0600
3711 @@ -0,0 +1,159 @@
3712 +#include <zebra.h>
3713 +#include "prefix.h"
3714 +#include "table.h"
3716 +#include "ldp_struct.h"
3717 +#include "mpls_mm_impl.h"
3718 +#include "mpls_tree_impl.h"
3720 +mpls_tree_handle mpls_tree_create(int depth)
3722 + return route_table_init();
3725 +mpls_return_enum mpls_tree_insert(mpls_tree_handle tree, uint32_t key, int length,
3726 + void *info)
3728 + struct route_node *node;
3729 + struct prefix p;
3731 + p.family = AF_INET;
3732 + p.prefixlen = length;
3733 + p.u.prefix4.s_addr = key;
3735 + if ((node = route_node_get(tree,&p))) {
3736 + /* result is that the node is 'held', it will be held */
3737 + /* until it is deleted from the tree */
3738 + node->info = info;
3739 + return MPLS_SUCCESS;
3741 + return MPLS_FAILURE;
3744 +mpls_return_enum mpls_tree_remove(mpls_tree_handle tree, uint32_t key,
3745 + int length, void **info)
3747 + struct route_node *node;
3748 + struct prefix p;
3750 + p.family = AF_INET;
3751 + p.prefixlen = length;
3752 + p.u.prefix4.s_addr = key;
3754 + if ((node = route_node_lookup(tree,&p))) {
3755 + *info = node->info;
3756 + node->info = NULL;
3757 + route_unlock_node(node);
3758 + route_unlock_node(node);
3759 + return MPLS_SUCCESS;
3761 + return MPLS_FAILURE;
3764 +mpls_return_enum mpls_tree_replace(mpls_tree_handle tree, uint32_t key, int length,
3765 + void *new, void **old)
3767 + struct route_node *node;
3768 + struct prefix p;
3770 + p.family = AF_INET;
3771 + p.prefixlen = length;
3772 + p.u.prefix4.s_addr = key;
3774 + if ((node = route_node_lookup(tree,&p))) {
3775 + *old = node->info;
3776 + node->info = new;
3777 + route_unlock_node(node);
3778 + return MPLS_SUCCESS;
3780 + return MPLS_FAILURE;
3783 +mpls_return_enum mpls_tree_get(mpls_tree_handle tree, uint32_t key, int length,
3784 + void **info)
3786 + struct route_node *node;
3787 + struct prefix p;
3789 + p.family = AF_INET;
3790 + p.prefixlen = length;
3791 + p.u.prefix4.s_addr = key;
3793 + if ((node = route_node_lookup(tree,&p))) {
3794 + *info = node->info;
3795 + route_unlock_node(node);
3796 + return MPLS_SUCCESS;
3798 + return MPLS_FAILURE;
3801 +mpls_return_enum mpls_tree_get_longest(mpls_tree_handle tree, uint32_t key,
3802 + void **info)
3804 + struct route_node *node;
3805 + struct prefix p;
3807 + p.family = AF_INET;
3808 + p.prefixlen = 0;
3809 + p.u.prefix4.s_addr = key;
3811 + if ((node = route_node_match(tree,&p))) {
3812 + *info = node->info;
3813 + route_unlock_node(node);
3814 + return MPLS_SUCCESS;
3816 + return MPLS_FAILURE;
3819 +void mpls_tree_dump(const mpls_tree_handle tree, ldp_tree_callback callback)
3823 +void mpls_tree_delete(mpls_tree_handle tree)
3825 + route_table_finish(tree);
3828 +mpls_return_enum mpls_tree_getfirst(mpls_tree_handle tree, uint32_t * key,
3829 + int *length, void **info)
3831 + struct route_node *node;
3832 + struct prefix p;
3834 + p.family = AF_INET;
3835 + p.prefixlen = 0;
3836 + p.u.prefix4.s_addr = 0;
3838 + if ((node = route_node_match(tree,&p))) {
3839 + *info = node->info;
3840 + *length = node->p.prefixlen;
3841 + *key = node->p.u.prefix4.s_addr;
3842 + route_unlock_node(node);
3843 + return MPLS_SUCCESS;
3845 + return MPLS_FAILURE;
3848 +mpls_return_enum mpls_tree_getnext(mpls_tree_handle tree, uint32_t * key,
3849 + int *length, void **info)
3851 + struct route_node *node;
3852 + struct prefix p;
3854 + p.family = AF_INET;
3855 + p.prefixlen = *length;
3856 + p.u.prefix4.s_addr = *key;
3858 + if (!(node = route_node_match(tree,&p))) {
3859 + return MPLS_FAILURE;
3862 + if ((node = route_next(node))) {
3863 + *info = node->info;
3864 + *length = node->p.prefixlen;
3865 + *key = node->p.u.prefix4.s_addr;
3866 + route_unlock_node(node);
3867 + return MPLS_SUCCESS;
3869 + return MPLS_FAILURE;
3871 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/l2cc_interface.c quagga-mpls/ldpd/l2cc_interface.c
3872 --- quagga/ldpd/l2cc_interface.c 1969-12-31 18:00:00.000000000 -0600
3873 +++ quagga-mpls/ldpd/l2cc_interface.c 2006-08-09 22:02:24.000000000 -0500
3874 @@ -0,0 +1,98 @@
3875 +#include <zebra.h>
3876 +#include "memory.h"
3878 +#include "ldp.h"
3879 +#include "ldp_cfg.h"
3880 +#include "ldp_struct.h"
3882 +#include "ldp_interface.h"
3884 +struct l2cc_interface *l2cc_if_new(struct ldp_interface *mi) {
3885 + struct l2cc_interface *li;
3887 + li = XMALLOC(MTYPE_LDP, sizeof(struct l2cc_interface));
3888 + memset(li, 0, sizeof(struct l2cc_interface));
3889 + li->mi = mi;
3891 + li->admin_up = MPLS_BOOL_TRUE;
3892 + li->create_on_hold = MPLS_BOOL_FALSE;
3894 + return li;
3897 +void l2cc_if_free(struct l2cc_interface *li) {
3898 + XFREE(MTYPE_LDP, li);
3901 +void l2cc_interface_create(struct ldp_interface *mi) {
3902 + struct ldp *ldp = ldp_get();
3904 + mi->l2cc->create_on_hold = MPLS_BOOL_FALSE;
3906 + ldp_cfg_fec_set(ldp->h, &mi->l2cc->l2cc, LDP_CFG_ADD);
3907 + ldp_cfg_fec_get(ldp->h, &mi->l2cc->l2cc, 0xFFFFFFFF);
3909 + l2cc_interface_admin_state_finish(mi);
3912 +void l2cc_interface_delete(struct ldp_interface *mi) {
3913 + struct ldp *ldp = ldp_get();
3915 + mi->l2cc->create_on_hold = MPLS_BOOL_TRUE;
3917 + if (ldp) {
3918 + l2cc_interface_admin_state_start(mi);
3919 + ldp_cfg_fec_set(ldp->h, &mi->l2cc->l2cc, LDP_CFG_DEL);
3921 + mi->l2cc->l2cc.index = 0;
3924 +int l2cc_interface_startup(struct ldp_interface *mi) {
3925 + struct ldp *ldp = ldp_get();
3927 + if (!mi->l2cc->l2cc.index) {
3928 + return MPLS_FAILURE;
3931 + ldp_cfg_fec_set(ldp->h, &mi->l2cc->l2cc, LDP_CFG_ADD);
3933 + return MPLS_SUCCESS;
3936 +int l2cc_interface_shutdown(struct ldp_interface *mi) {
3937 + struct ldp *ldp = ldp_get();
3939 + if (!mi->l2cc->l2cc.index) {
3940 + return MPLS_FAILURE;
3943 + ldp_cfg_fec_set(ldp->h, &mi->l2cc->l2cc, LDP_CFG_DEL);
3945 + return MPLS_SUCCESS;
3948 +int l2cc_interface_admin_state_start(struct ldp_interface *mi) {
3949 + if (mi->l2cc->admin_up == MPLS_BOOL_TRUE && ldp_interface_is_up(mi)) {
3950 + return l2cc_interface_shutdown(mi);
3952 + return MPLS_SUCCESS;
3955 +int l2cc_interface_admin_state_finish(struct ldp_interface *mi) {
3956 + if (mi->l2cc->admin_up == MPLS_BOOL_TRUE && ldp_interface_is_up(mi)) {
3957 + return l2cc_interface_startup(mi);
3959 + return MPLS_SUCCESS;
3962 +void l2cc_if_up(struct ldp_interface *mi) {
3963 + if (mi->l2cc && mi->l2cc->admin_up == MPLS_BOOL_TRUE) {
3964 + l2cc_interface_startup(mi);
3968 +void l2cc_if_down(struct ldp_interface *mi) {
3969 + if (mi->l2cc && mi->l2cc->admin_up == MPLS_BOOL_TRUE) {
3970 + l2cc_interface_shutdown(mi);
3973 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/l2cc_interface.h quagga-mpls/ldpd/l2cc_interface.h
3974 --- quagga/ldpd/l2cc_interface.h 1969-12-31 18:00:00.000000000 -0600
3975 +++ quagga-mpls/ldpd/l2cc_interface.h 2006-08-09 22:02:25.000000000 -0500
3976 @@ -0,0 +1,29 @@
3977 +#ifndef L2CC_IF_H
3978 +#define L2CC_IF_H
3980 +#include "ldp_struct.h"
3982 +struct ldp_interface;
3984 +struct l2cc_interface {
3985 + struct ldp_interface *mi;
3986 + mpls_fec l2cc;
3987 + mpls_bool admin_up;
3988 + mpls_bool create_on_hold;
3991 +struct l2cc_interface *l2cc_if_new(struct ldp_interface *mi);
3992 +void l2cc_if_free(struct l2cc_interface *li);
3994 +void l2cc_if_up(struct ldp_interface *mi);
3995 +void l2cc_if_down(struct ldp_interface *mi);
3997 +int l2cc_interface_startup(struct ldp_interface *mi);
3998 +int l2cc_interface_shutdown(struct ldp_interface *mi);
4000 +void l2cc_interface_create(struct ldp_interface *mi);
4001 +void l2cc_interface_delete(struct ldp_interface *mi);
4002 +int l2cc_interface_admin_state_start(struct ldp_interface *mi);
4003 +int l2cc_interface_admin_state_finish(struct ldp_interface *mi);
4005 +#endif
4006 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_addr.c quagga-mpls/ldpd/ldp_addr.c
4007 --- quagga/ldpd/ldp_addr.c 1969-12-31 18:00:00.000000000 -0600
4008 +++ quagga-mpls/ldpd/ldp_addr.c 2006-12-07 22:14:56.000000000 -0600
4009 @@ -0,0 +1,377 @@
4012 + * Copyright (C) James R. Leu 2000
4013 + * jleu@mindspring.com
4015 + * This software is covered under the LGPL, for more
4016 + * info check out http://www.gnu.org/copyleft/lgpl.html
4017 + */
4019 +#include <stdlib.h>
4020 +#include <string.h>
4021 +#include <sys/socket.h>
4022 +#include "ldp_struct.h"
4023 +#include "ldp_global.h"
4024 +#include "ldp_session.h"
4025 +#include "ldp_entity.h"
4026 +#include "ldp_pdu_setup.h"
4027 +#include "ldp_addr.h"
4028 +#include "ldp_nexthop.h"
4029 +#include "ldp_if.h"
4030 +#include "ldp_buf.h"
4031 +#include "ldp_mesg.h"
4032 +#include "mpls_list.h"
4033 +#include "mpls_ifmgr_impl.h"
4034 +#include "mpls_mm_impl.h"
4035 +#include "mpls_trace_impl.h"
4036 +#include "mpls_tree_impl.h"
4038 +static uint32_t _ldp_addr_next_index = 1;
4040 +ldp_addr *ldp_addr_create(ldp_global *g, mpls_inet_addr * address)
4042 + ldp_addr *a = (ldp_addr *) mpls_malloc(sizeof(ldp_addr));
4044 + LDP_ENTER(g->user_data, "ldp_addr_create: 0x%08x", address->u.ipv4);
4045 + if (a) {
4046 + /*
4047 + * note: this is init to 1 for a reason!
4048 + * We're placing it in the global list, so this is our refcnt
4049 + * when this refcnt gets to zero, it will be removed from the
4050 + * global list and deleted
4051 + */
4052 + /*
4053 + * TESTING: jleu 6/7/2004, since I want the addr to be cleaned up
4054 + * when it no longer has a nexthop, fec, or label, the only things that
4055 + * should increment the ref are those (nh, fec, label etc), not global
4056 + * nor inserting into the tree.
4057 + MPLS_REFCNT_INIT(a, 1);
4058 + */
4059 + MPLS_REFCNT_INIT(a, 0);
4060 + MPLS_LIST_INIT(&a->nh_root, ldp_nexthop);
4061 + MPLS_LIST_ELEM_INIT(a, _global);
4062 + MPLS_LIST_ELEM_INIT(a, _if);
4063 + memcpy(&a->address, address, sizeof(mpls_inet_addr));
4064 + a->index = _ldp_addr_get_next_index();
4065 + a->session = NULL;
4066 + _ldp_global_add_addr(g, a);
4067 + ldp_addr_insert2(g, a);
4069 + LDP_EXIT(g->user_data, "ldp_addr_create: %p", a);
4070 + return a;
4073 +void ldp_addr_delete(ldp_global *g, ldp_addr * a)
4075 + LDP_PRINT(g->user_data, "addr delete: %p", a);
4076 + MPLS_REFCNT_ASSERT(a, 0);
4077 + ldp_addr_remove(g, &a->address);
4078 + _ldp_global_del_addr(g, a);
4079 + mpls_free(a);
4082 +ldp_addr *ldp_addr_find(ldp_global *g, mpls_inet_addr * address)
4084 + ldp_addr *addr = NULL;
4086 + LDP_ENTER(g->user_data, "ldp_addr_find: 0x%08x", address->u.ipv4);
4087 + if (mpls_tree_get(g->addr_tree, address->u.ipv4, 32, (void **)&addr) !=
4088 + MPLS_SUCCESS) {
4089 + LDP_EXIT(g->user_data, "ldp_addr_find: NULL");
4090 + return NULL;
4092 + LDP_EXIT(g->user_data, "ldp_addr_find: %p", addr);
4093 + return addr;
4096 +ldp_addr *ldp_addr_insert(ldp_global *g, mpls_inet_addr * address)
4098 + ldp_addr *addr = NULL;
4100 + if ((addr = ldp_addr_create(g, address)) == NULL) {
4101 + LDP_PRINT(g->user_data, "ldp_addr_insert: error creating address\n");
4102 + return NULL;
4104 + return addr;
4107 +mpls_return_enum ldp_addr_insert2(ldp_global *g, ldp_addr *addr)
4109 + LDP_ENTER(g->user_data, "ldp_addr_insert2: 0x%08x", addr->address.u.ipv4);
4110 + if (mpls_tree_insert(g->addr_tree, addr->address.u.ipv4, 32, (void *)addr) !=
4111 + MPLS_SUCCESS) {
4112 + LDP_EXIT(g->user_data, "ldp_addr_insert2-error");
4113 + MPLS_REFCNT_RELEASE2(g, addr, ldp_addr_delete);
4114 + return MPLS_FATAL;
4116 + LDP_EXIT(g->user_data, "ldp_addr_insert2");
4117 + return MPLS_SUCCESS;
4120 +void ldp_addr_remove(ldp_global *g, mpls_inet_addr * address)
4122 + ldp_addr *addr = NULL;
4123 + mpls_tree_remove(g->addr_tree, address->u.ipv4, 32, (void **)&addr);
4126 +void ldp_addr_add_if(ldp_addr * a, ldp_if * i)
4128 + MPLS_ASSERT(a && i);
4129 + MPLS_REFCNT_HOLD(i);
4130 + a->iff = i;
4133 +void ldp_addr_del_if(ldp_global *g, ldp_addr * a)
4135 + MPLS_ASSERT(a);
4136 + MPLS_REFCNT_RELEASE2(g, a->iff, ldp_if_delete);
4137 + a->iff = NULL;
4140 +mpls_bool ldp_addr_is_empty(ldp_addr *a)
4142 + if ((a->iff == NULL) && MPLS_LIST_EMPTY(&a->nh_root) &&
4143 + (a->session == NULL)) {
4144 + return MPLS_BOOL_TRUE;
4146 + return MPLS_BOOL_FALSE;
4149 +mpls_return_enum _ldp_addr_add_session(ldp_addr * a, ldp_session * s)
4151 + MPLS_ASSERT(a && s);
4152 + MPLS_REFCNT_HOLD(s);
4153 + a->session = s;
4154 + return MPLS_SUCCESS;
4157 +void _ldp_addr_del_session(ldp_addr * a, ldp_session * s)
4159 + MPLS_ASSERT(a && s);
4160 + a->session = NULL;
4161 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
4165 + * We do not hold a ref to the nexthop. The nexthop holds a ref to the
4166 + * addr. Nexthop creation calls ldp_addr_add_nexthop, nexthop deletion
4167 + * calls ldp_addr_del_nexthop. There is no way a nexthop can be deleted
4168 + * without removing the addrs ref to the nexthop.
4169 + */
4170 +void ldp_addr_add_nexthop(ldp_addr * a, ldp_nexthop * nh)
4172 + ldp_nexthop *np = NULL;
4174 + MPLS_ASSERT(a && nh);
4176 + ldp_nexthop_add_addr(nh,a);
4178 + np = MPLS_LIST_HEAD(&a->nh_root);
4179 + while (np != NULL) {
4180 + if (np->index > nh->index) {
4181 + MPLS_LIST_INSERT_BEFORE(&a->nh_root, np, nh, _addr);
4182 + return;
4184 + np = MPLS_LIST_NEXT(&a->nh_root, np, _addr);
4186 + MPLS_LIST_ADD_TAIL(&a->nh_root, nh, _addr, ldp_nexthop);
4189 +void ldp_addr_del_nexthop(ldp_global *g, ldp_addr * a, ldp_nexthop * nh)
4191 + MPLS_ASSERT(a && nh);
4192 + MPLS_LIST_REMOVE(&a->nh_root, nh, _addr);
4193 + ldp_nexthop_del_addr(g, nh);
4196 +uint32_t _ldp_addr_get_next_index()
4198 + uint32_t retval = _ldp_addr_next_index;
4200 + _ldp_addr_next_index++;
4201 + if (retval > _ldp_addr_next_index) {
4202 + _ldp_addr_next_index = 1;
4204 + return retval;
4207 +void ldp_addr_mesg_prepare(ldp_mesg * msg, ldp_global * g, uint32_t msgid,
4208 + mpls_inet_addr * addr)
4210 + MPLS_MSGPTR(Adr);
4212 + LDP_ENTER(g->user_data, "ldp_addr_mesg_prepare");
4214 + ldp_mesg_prepare(msg, MPLS_ADDR_MSGTYPE, msgid);
4215 + MPLS_MSGPARAM(Adr) = &msg->u.addr;
4217 + MPLS_MSGPARAM(Adr)->adrListTlvExists = 1;
4218 + MPLS_MSGPARAM(Adr)->baseMsg.msgLength +=
4219 + setupAddrTlv(&(MPLS_MSGPARAM(Adr)->addressList));
4221 + MPLS_MSGPARAM(Adr)->baseMsg.msgLength +=
4222 + addAddrElem2AddrTlv(&(MPLS_MSGPARAM(Adr)->addressList), addr->u.ipv4);
4224 + LDP_EXIT(g->user_data, "ldp_addr_mesg_prepare");
4227 +void ldp_waddr_mesg_prepare(ldp_mesg * msg, ldp_global * g, uint32_t msgid,
4228 + mpls_inet_addr * addr)
4230 + MPLS_MSGPTR(Adr);
4232 + LDP_ENTER(g->user_data, "ldp_waddr_mesg_prepare");
4234 + ldp_mesg_prepare(msg, MPLS_ADDRWITH_MSGTYPE, msgid);
4235 + MPLS_MSGPARAM(Adr) = &msg->u.addr;
4237 + MPLS_MSGPARAM(Adr)->adrListTlvExists = 1;
4238 + MPLS_MSGPARAM(Adr)->baseMsg.msgLength +=
4239 + setupAddrTlv(&(MPLS_MSGPARAM(Adr)->addressList));
4241 + MPLS_MSGPARAM(Adr)->baseMsg.msgLength +=
4242 + addAddrElem2AddrTlv(&(MPLS_MSGPARAM(Adr)->addressList), addr->u.ipv4);
4244 + LDP_EXIT(g->user_data, "ldp_waddr_mesg_prepare");
4247 +mpls_return_enum ldp_addr_send(ldp_global * g, ldp_session * s,
4248 + mpls_inet_addr * a)
4250 + mpls_return_enum result = MPLS_FAILURE;
4252 + MPLS_ASSERT(s && a);
4254 + LDP_ENTER(g->user_data, "ldp_addr_send");
4256 + ldp_addr_mesg_prepare(s->tx_message, g, g->message_identifier++, a);
4258 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_ADDRESS,
4259 + "Addr Send: session(%d)\n", s->index);
4261 + result = ldp_mesg_send_tcp(g, s, s->tx_message);
4263 + LDP_EXIT(g->user_data, "ldp_addr_send");
4265 + return result;
4268 +mpls_return_enum ldp_waddr_send(ldp_global * g, ldp_session * s,
4269 + mpls_inet_addr * a)
4271 + mpls_return_enum result = MPLS_FAILURE;
4273 + MPLS_ASSERT(s && a);
4275 + LDP_ENTER(g->user_data, "ldp_waddr_send");
4277 + ldp_waddr_mesg_prepare(s->tx_message, g, g->message_identifier++, a);
4279 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_ADDRESS,
4280 + "Addr Withdraw Send: session(%d)\n", s->index);
4282 + result = ldp_mesg_send_tcp(g, s, s->tx_message);
4284 + LDP_EXIT(g->user_data, "ldp_waddr_send");
4286 + return result;
4289 +mpls_return_enum ldp_addr_process(ldp_global * g, ldp_session * s,
4290 + ldp_entity * e, ldp_mesg * msg)
4292 + mplsLdpAdrMsg_t *body = &msg->u.addr;
4293 + mpls_inet_addr inet;
4294 + ldp_addr *addr = NULL;
4295 + ldp_nexthop *nh = NULL;
4296 + ldp_fec *fec = NULL;
4297 + int len = (body->addressList.baseTlv.length - MPLS_ADDFAMFIXLEN) /
4298 + MPLS_IPv4LEN;
4299 + int i;
4301 + LDP_ENTER(g->user_data, "ldp_addr_process");
4303 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_ADDRESS,
4304 + "Addr Recv: session(%d)\n", s->index);
4306 + for (i = 0; i < len; i++) {
4307 + inet.type = MPLS_FAMILY_IPV4;
4308 + inet.u.ipv4 = body->addressList.address[i];
4310 + if (msg->u.generic.flags.flags.msgType == MPLS_ADDR_MSGTYPE) {
4311 + if (!(addr = ldp_addr_find(g, &inet))) {
4312 + /* it's not in the tree, put it there! */
4313 + if ((addr = ldp_addr_insert(g, &inet)) == NULL) {
4314 + LDP_PRINT(g->user_data, "ldp_addr_process: error adding addr\n");
4315 + goto ldp_addr_process_end;
4319 + /* the addr is in the tree */
4320 + if (addr->session) {
4321 + LDP_PRINT(g->user_data,
4322 + "ldp_addr_process: session (%d) already advertised this address\n",
4323 + addr->session->index);
4324 + return MPLS_FAILURE;
4327 + if (ldp_session_add_addr(g, s, addr) == MPLS_FAILURE) {
4328 + LDP_PRINT(g->user_data,
4329 + "ldp_addr_process: error adding address to session\n");
4330 + return MPLS_FAILURE;
4333 + nh = MPLS_LIST_HEAD(&addr->nh_root);
4334 + while (nh != NULL) {
4335 + fec = nh->fec;
4336 + /* create cross connect */
4337 + /* send label mapping */
4338 + nh = MPLS_LIST_NEXT(&addr->nh_root, nh, _addr);
4340 + } else {
4341 + /* addr withdrawl */
4342 + if ((addr = ldp_addr_find(g, &inet))) {
4343 + nh = MPLS_LIST_HEAD(&addr->nh_root);
4344 + while (fec != NULL) {
4345 + /* send label withdrawl */
4346 + /* delete cross connect */
4347 + nh = MPLS_LIST_NEXT(&addr->nh_root, nh, _addr);
4350 + ldp_session_del_addr(g, s, addr);
4355 + LDP_EXIT(g->user_data, "ldp_addr_process");
4357 + return MPLS_SUCCESS;
4359 +ldp_addr_process_end:
4361 + LDP_EXIT(g->user_data, "ldp_addr_process-error");
4363 + return MPLS_FAILURE;
4366 +void ldp_addr_process_add(ldp_global *g, struct ldp_addr *a)
4368 + ldp_session* sp = MPLS_LIST_HEAD(&g->session);
4369 + while (sp != NULL) {
4370 + if (sp->state == LDP_STATE_OPERATIONAL) {
4371 + ldp_addr_send(g, sp, &a->address);
4373 + sp = MPLS_LIST_NEXT(&g->session, sp, _global);
4377 +void ldp_addr_process_remove(ldp_global *g, struct ldp_addr *a)
4379 + ldp_session* sp = MPLS_LIST_HEAD(&g->session);
4380 + while (sp != NULL) {
4381 + if (sp->state == LDP_STATE_OPERATIONAL) {
4382 + ldp_waddr_send(g, sp, &a->address);
4384 + sp = MPLS_LIST_NEXT(&g->session, sp, _global);
4387 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_addr.h quagga-mpls/ldpd/ldp_addr.h
4388 --- quagga/ldpd/ldp_addr.h 1969-12-31 18:00:00.000000000 -0600
4389 +++ quagga-mpls/ldpd/ldp_addr.h 2006-08-09 21:56:11.000000000 -0500
4390 @@ -0,0 +1,42 @@
4393 + * Copyright (C) James R. Leu 2000
4394 + * jleu@mindspring.com
4396 + * This software is covered under the LGPL, for more
4397 + * info check out http://www.gnu.org/copyleft/lgpl.html
4398 + */
4400 +#ifndef _LDP_ADDR_H_
4401 +#define _LDP_ADDR_H_
4403 +#include "ldp_struct.h"
4405 +extern ldp_addr *ldp_addr_find(ldp_global *g, mpls_inet_addr * address);
4406 +extern mpls_return_enum ldp_addr_insert2(ldp_global *g, ldp_addr *addr);
4407 +extern ldp_addr *ldp_addr_insert(ldp_global *g, mpls_inet_addr * address);
4408 +extern void ldp_addr_remove(ldp_global *g, mpls_inet_addr * address);
4409 +extern ldp_addr *ldp_addr_create(ldp_global *g, mpls_inet_addr * inet);
4410 +extern void ldp_addr_delete(ldp_global *g, ldp_addr * a);
4411 +extern void ldp_addr_add_if(ldp_addr * a, ldp_if * i);
4412 +extern void ldp_addr_del_if(ldp_global *g, ldp_addr * a);
4413 +extern mpls_bool ldp_addr_is_empty(ldp_addr *a);
4414 +extern mpls_return_enum _ldp_addr_add_session(ldp_addr * a, ldp_session * s);
4415 +extern void _ldp_addr_del_session(ldp_addr * a, ldp_session * s);
4416 +extern void ldp_addr_add_nexthop(ldp_addr * a, ldp_nexthop * nh);
4417 +extern void ldp_addr_del_nexthop(ldp_global *g, ldp_addr * a, ldp_nexthop * nh);
4418 +extern uint32_t _ldp_addr_get_next_index();
4420 +extern void ldp_addr_mesg_prepare(ldp_mesg * msg, ldp_global * g,
4421 + uint32_t msgid, mpls_inet_addr * a);
4423 +extern mpls_return_enum ldp_addr_send(ldp_global * g, ldp_session * s,
4424 + mpls_inet_addr * a);
4425 +extern mpls_return_enum ldp_waddr_send(ldp_global * g, ldp_session * s,
4426 + mpls_inet_addr * a);
4427 +extern mpls_return_enum ldp_addr_process(ldp_global * g, ldp_session * s,
4428 + ldp_entity * e, ldp_mesg * msg);
4429 +extern void ldp_addr_process_add(ldp_global *g, struct ldp_addr *a);
4430 +extern void ldp_addr_process_remove(ldp_global *g, struct ldp_addr *a);
4432 +#endif
4433 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_adj.c quagga-mpls/ldpd/ldp_adj.c
4434 --- quagga/ldpd/ldp_adj.c 1969-12-31 18:00:00.000000000 -0600
4435 +++ quagga-mpls/ldpd/ldp_adj.c 2006-12-07 22:14:22.000000000 -0600
4436 @@ -0,0 +1,286 @@
4439 + * Copyright (C) James R. Leu 2000
4440 + * jleu@mindspring.com
4442 + * This software is covered under the LGPL, for more
4443 + * info check out http://www.gnu.org/copyleft/lgpl.html
4444 + */
4446 +#include <stdlib.h>
4447 +#include <sys/socket.h>
4448 +#include "ldp_struct.h"
4449 +#include "ldp_global.h"
4450 +#include "ldp_session.h"
4451 +#include "ldp_hello.h"
4452 +#include "ldp_global.h"
4453 +#include "ldp_entity.h"
4454 +#include "ldp_adj.h"
4455 +#include "ldp_peer.h"
4456 +#include "mpls_mm_impl.h"
4457 +#include "mpls_assert.h"
4458 +#include "mpls_timer_impl.h"
4459 +#include "mpls_lock_impl.h"
4460 +#include "mpls_trace_impl.h"
4462 +static uint32_t _ldp_adj_next_index = 1;
4464 +ldp_adj *ldp_adj_create(mpls_inet_addr * source, mpls_inet_addr * lsraddr,
4465 + int labelspace, int remote_hellotime,
4466 + mpls_inet_addr * remote_transport_address, uint32_t remote_csn)
4468 + ldp_adj *a = (ldp_adj *) mpls_malloc(sizeof(ldp_adj));
4469 + struct in_addr addr;
4471 + if (lsraddr == NULL || source == NULL)
4472 + return NULL;
4474 + if (a) {
4475 + memset(a, 0, sizeof(ldp_adj));
4476 + MPLS_REFCNT_INIT(a, 0);
4477 + MPLS_LIST_ELEM_INIT(a, _global);
4478 + MPLS_LIST_ELEM_INIT(a, _session);
4479 + MPLS_LIST_ELEM_INIT(a, _entity);
4481 + a->index = _ldp_adj_get_next_index();
4483 + /* these are operational values */
4484 + /* JLEU: where do I grab these values from */
4486 + /* these values are learned form the remote peer */
4487 + memcpy(&a->remote_source_address, source, sizeof(mpls_inet_addr));
4488 + memcpy(&a->remote_lsr_address, lsraddr, sizeof(mpls_inet_addr));
4490 + addr.s_addr = htonl(lsraddr->u.ipv4);
4491 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_PERIODIC,
4492 + "Adj(%d) created for %s/",a->index, inet_ntoa(addr));
4493 + addr.s_addr = htonl(source->u.ipv4);
4494 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_PERIODIC,
4495 + "%s\n",inet_ntoa(addr));
4497 + if (remote_transport_address) {
4498 + memcpy(&a->remote_transport_address, remote_transport_address,
4499 + sizeof(mpls_inet_addr));
4500 + } else {
4501 + memset(&a->remote_transport_address, 0, sizeof(mpls_inet_addr));
4504 + a->remote_hellotime = remote_hellotime;
4505 + a->remote_csn = remote_csn;
4506 + a->state = MPLS_OPER_DOWN;
4507 + a->role = LDP_NONE;
4509 + return a;
4512 +void ldp_adj_delete(ldp_adj * a)
4514 + LDP_PRINT(NULL,"adj delete %p", a);
4515 + MPLS_REFCNT_ASSERT(a, 0);
4516 + mpls_free(a);
4519 +mpls_return_enum ldp_adj_startup(ldp_global * g, ldp_adj * a, int request)
4521 + ldp_entity *e;
4523 + MPLS_ASSERT(a && (e = a->entity));
4524 + /* with recent changes to when the session gets created I think this
4525 + * assert is not longer valid - jleu 2003-02-20
4526 + MPLS_ASSERT(!a->session);
4527 + */
4528 + MPLS_ASSERT(a->state != LDP_NONE);
4530 + LDP_ENTER(g->user_data, "ldp_adj_startup");
4532 + /* ldp-11 3.5.2. Hello Message */
4533 + if (e->hellotime_timer != 0xFFFF) {
4534 + MPLS_REFCNT_HOLD(a);
4535 + a->hellotime_recv_timer = mpls_timer_create(g->timer_handle, MPLS_UNIT_SEC,
4536 + e->hellotime_timer, (void *)a, g, ldp_hello_timeout_callback);
4538 + if (mpls_timer_handle_verify(g->timer_handle, a->hellotime_recv_timer) ==
4539 + MPLS_BOOL_FALSE) {
4540 + MPLS_REFCNT_RELEASE(a, ldp_adj_delete);
4541 + goto ldp_adj_startup_error;
4545 + if (request && mpls_timer_handle_verify(g->timer_handle,
4546 + e->p.peer->hellotime_send_timer) == MPLS_BOOL_FALSE) {
4547 + /* request is ONLY specific with indirect adj */
4548 + ldp_hello_send(g, e);
4551 + a->state = MPLS_OPER_UP;
4553 + if (e->hellotime_timer != 0xFFFF) {
4554 + mpls_timer_start(g->timer_handle, a->hellotime_recv_timer,
4555 + MPLS_TIMER_ONESHOT);
4558 + LDP_EXIT(g->user_data, "ldp_adj_startup");
4560 + return MPLS_SUCCESS;
4562 +ldp_adj_startup_error:
4564 + LDP_EXIT(g->user_data, "ldp_adj_startup: error");
4566 + return MPLS_FAILURE;
4569 +#if 0 /* no one used this? */
4570 +mpls_return_enum ldp_adj_restart(ldp_global * g, ldp_adj * a)
4573 + LDP_ENTER(g->user_data, "ldp_adj_restart");
4575 + if (a->session != NULL) {
4576 + ldp_session_shutdown(g, a->session);
4577 + /* session_shutdown does this already ldp_adj_del_session(a); */
4579 + mpls_timer_stop(g->timer_handle, a->hellotime_recv_timer);
4580 + mpls_timer_start(g->timer_handle, a->hellotime_recv_timer, MPLS_TIMER_ONESHOT);
4582 + LDP_EXIT(g->user_data, "ldp_adj_restart");
4584 + return MPLS_SUCCESS;
4586 +#endif
4588 +mpls_return_enum ldp_adj_shutdown(ldp_global * g, ldp_adj * a)
4590 + ldp_entity *e;
4592 + MPLS_ASSERT(g && a && (e = a->entity));
4594 + LDP_ENTER(g->user_data, "ldp_adj_shutdown");
4596 + MPLS_REFCNT_HOLD(a);
4598 + if (a->session) {
4599 + ldp_session_shutdown(g, a->session, MPLS_BOOL_TRUE);
4600 + /* session_shutdown does ldp_adj_del_session(a); */
4603 + ldp_adj_recv_stop(g, a);
4605 + if (e->entity_type == LDP_INDIRECT &&
4606 + e->p.peer->target_role == LDP_PASSIVE) {
4607 + /* we started sending due to a targeted hello with "request"
4608 + * now that the adj is down we can stop
4609 + */
4610 + ldp_peer_send_stop(g, e->p.peer);
4613 + ldp_entity_del_adj(e, a);
4614 + if (a->state == MPLS_OPER_UP) {
4615 + _ldp_global_del_adj(g, a);
4618 + LDP_EXIT(g->user_data, "ldp_adj_shutdown");
4620 + MPLS_REFCNT_RELEASE(a, ldp_adj_delete);
4622 + return MPLS_SUCCESS;
4625 +mpls_return_enum ldp_adj_maintain_timer(ldp_global * g, ldp_adj * a)
4627 + mpls_return_enum retval;
4629 + LDP_ENTER(g->user_data, "ldp_adj_maintain_timer");
4631 + mpls_timer_stop(g->timer_handle, a->hellotime_recv_timer);
4632 + retval =
4633 + mpls_timer_start(g->timer_handle, a->hellotime_recv_timer, MPLS_TIMER_ONESHOT);
4635 + LDP_EXIT(g->user_data, "ldp_adj_maintain_timer");
4637 + return retval;
4640 +mpls_return_enum ldp_adj_recv_start(ldp_global * g, ldp_adj * a)
4642 + mpls_return_enum result = MPLS_SUCCESS;
4644 + LDP_ENTER(g->user_data, "ldp_adj_recv_start");
4646 + MPLS_REFCNT_HOLD(a);
4647 + a->hellotime_recv_timer = mpls_timer_create(g->timer_handle, MPLS_UNIT_SEC,
4648 + a->entity->hellotime_timer, (void *)a, g, ldp_hello_timeout_callback);
4650 + if (mpls_timer_handle_verify(g->timer_handle, a->hellotime_recv_timer) ==
4651 + MPLS_BOOL_FALSE) {
4652 + MPLS_REFCNT_RELEASE(a, ldp_adj_delete);
4653 + result = MPLS_FAILURE;
4656 + LDP_EXIT(g->user_data, "ldp_adj_recv_start");
4658 + return result;
4661 +mpls_return_enum ldp_adj_recv_stop(ldp_global * g, ldp_adj * a)
4664 + LDP_ENTER(g->user_data, "ldp_adj_recv_stop");
4666 + if (mpls_timer_handle_verify(g->timer_handle, a->hellotime_recv_timer) ==
4667 + MPLS_BOOL_TRUE) {
4668 + mpls_timer_stop(g->timer_handle, a->hellotime_recv_timer);
4669 + mpls_timer_delete(g->timer_handle, a->hellotime_recv_timer);
4670 + a->hellotime_recv_timer = (mpls_timer_handle) 0;
4671 + MPLS_REFCNT_RELEASE(a, ldp_adj_delete);
4674 + LDP_EXIT(g->user_data, "ldp_adj_recv_stop");
4676 + return MPLS_SUCCESS;
4679 +void _ldp_adj_add_entity(ldp_adj * a, ldp_entity * e)
4681 + MPLS_ASSERT(a && e);
4682 + MPLS_REFCNT_HOLD(e);
4683 + a->entity = e;
4686 +void _ldp_adj_del_entity(ldp_adj * a, ldp_entity *e)
4688 + MPLS_ASSERT(a && e);
4689 + MPLS_REFCNT_RELEASE(e, ldp_entity_delete);
4690 + a->entity = NULL;
4693 +void ldp_adj_add_session(ldp_adj * a, ldp_session * s)
4695 + MPLS_ASSERT(a && s);
4697 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_PERIODIC,
4698 + "Adj(%d) bound to sesssion(%d)\n",a->index,s->index);
4700 + MPLS_REFCNT_HOLD(s);
4701 + a->session = s;
4702 + _ldp_session_add_adj(s, a);
4705 +void ldp_adj_del_session(ldp_adj * a, ldp_session * s)
4707 + MPLS_ASSERT(a && s);
4708 + _ldp_session_del_adj(s, a);
4709 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
4710 + a->session = NULL;
4713 +uint32_t _ldp_adj_get_next_index()
4715 + uint32_t retval = _ldp_adj_next_index;
4717 + _ldp_adj_next_index++;
4718 + if (retval > _ldp_adj_next_index) {
4719 + _ldp_adj_next_index = 1;
4721 + return retval;
4723 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_adj.h quagga-mpls/ldpd/ldp_adj.h
4724 --- quagga/ldpd/ldp_adj.h 1969-12-31 18:00:00.000000000 -0600
4725 +++ quagga-mpls/ldpd/ldp_adj.h 2006-08-09 21:56:12.000000000 -0500
4726 @@ -0,0 +1,33 @@
4729 + * Copyright (C) James R. Leu 2000
4730 + * jleu@mindspring.com
4732 + * This software is covered under the LGPL, for more
4733 + * info check out http://www.gnu.org/copyleft/lgpl.html
4734 + */
4736 +#ifndef _LDP_ADJ_H_
4737 +#define _LDP_ADJ_H_
4739 +#include "ldp_struct.h"
4741 +extern ldp_adj *ldp_adj_create(mpls_inet_addr * source,
4742 + mpls_inet_addr * lsraddr, int labelspace, int remote_hellotime,
4743 + mpls_inet_addr * remote_transport_address, uint32_t remote_csn);
4745 +extern void ldp_adj_delete(ldp_adj * a);
4746 +extern mpls_return_enum ldp_adj_startup(ldp_global * g, ldp_adj * a,
4747 + int request);
4748 +extern mpls_return_enum ldp_adj_restart(ldp_global * g, ldp_adj * a);
4749 +extern mpls_return_enum ldp_adj_shutdown(ldp_global * g, ldp_adj * a);
4750 +extern mpls_return_enum ldp_adj_maintain_timer(ldp_global * g, ldp_adj * a);
4751 +extern mpls_return_enum ldp_adj_recv_stop(ldp_global * g, ldp_adj * a);
4753 +extern void _ldp_adj_add_entity(ldp_adj * a, ldp_entity * e);
4754 +extern void _ldp_adj_del_entity(ldp_adj * a, ldp_entity * e);
4755 +extern void ldp_adj_add_session(ldp_adj * a, ldp_session * s);
4756 +extern void ldp_adj_del_session(ldp_adj * a, ldp_session * s);
4757 +extern uint32_t _ldp_adj_get_next_index();
4759 +#endif
4760 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_attr.c quagga-mpls/ldpd/ldp_attr.c
4761 --- quagga/ldpd/ldp_attr.c 1969-12-31 18:00:00.000000000 -0600
4762 +++ quagga-mpls/ldpd/ldp_attr.c 2006-12-07 23:09:34.000000000 -0600
4763 @@ -0,0 +1,1050 @@
4766 + * Copyright (C) James R. Leu 2000
4767 + * jleu@mindspring.com
4769 + * This software is covered under the LGPL, for more
4770 + * info check out http://www.gnu.org/copyleft/lgpl.html
4771 + */
4773 +#include "ldp_struct.h"
4774 +#include "ldp_label_mapping.h"
4775 +#include "ldp_attr.h"
4776 +#include "ldp_if.h"
4777 +#include "ldp_addr.h"
4778 +#include "ldp_fec.h"
4779 +#include "ldp_global.h"
4780 +#include "ldp_inlabel.h"
4781 +#include "ldp_outlabel.h"
4782 +#include "ldp_session.h"
4783 +#include "mpls_refcnt.h"
4784 +#include "mpls_mm_impl.h"
4785 +#include "mpls_tree_impl.h"
4786 +#include "mpls_trace_impl.h"
4788 +#if MPLS_USE_LSR
4789 +#include "lsr_cfg.h"
4790 +#else
4791 +#include "mpls_mpls_impl.h"
4792 +#endif
4794 +static ldp_fec *_ldp_attr_get_fec2(ldp_global * g, mpls_fec * f, mpls_bool flag);
4795 +static ldp_fec *_ldp_attr_get_fec(ldp_global * g, ldp_attr * a, mpls_bool flag);
4796 +static ldp_fs *_ldp_fec_add_fs_ds(ldp_fec * fec, ldp_session * s);
4797 +static ldp_fs *_ldp_fec_add_fs_us(ldp_fec * fec, ldp_session * s);
4798 +static ldp_fs *_ldp_fec_find_fs_us(ldp_fec * fec, ldp_session * s,
4799 + mpls_bool flag);
4800 +static ldp_fs *_ldp_fec_find_fs_ds(ldp_fec * fec, ldp_session * s,
4801 + mpls_bool flag);
4802 +static void _ldp_fec_del_fs_us(ldp_fec * fec, ldp_fs * fs);
4803 +static void _ldp_fec_del_fs_ds(ldp_fec * fec, ldp_fs * fs);
4804 +static ldp_fs *_ldp_fs_create(ldp_session * s);
4805 +static void _ldp_fs_delete(ldp_fs * fs);
4806 +static ldp_attr *_ldp_fs_find_attr(ldp_fs * fs, ldp_attr * a);
4807 +static mpls_return_enum _ldp_fs_add_attr(ldp_fs * fs, ldp_attr * a);
4808 +static mpls_bool _ldp_fs_del_attr(ldp_global *g, ldp_fs * fs, ldp_attr * a);
4809 +static uint32_t _ldp_attr_get_next_index();
4811 +static uint32_t _ldp_attr_next_index = 1;
4813 +int ldp_attr_num_us2ds(ldp_attr * ds)
4815 + ldp_attr *attr = NULL;
4816 + int count = 0;
4818 + attr = MPLS_LIST_HEAD(&ds->us_attr_root);
4819 + while (attr) {
4820 + count++;
4821 + attr = MPLS_LIST_NEXT(&ds->us_attr_root, attr, _ds_attr);
4823 + return count;
4826 +mpls_bool ldp_attr_us_partof_ds(ldp_attr * us, ldp_attr * ds)
4828 + if (us->ds_attr == ds) {
4829 + return MPLS_BOOL_TRUE;
4831 + return MPLS_BOOL_FALSE;
4834 +void ldp_attr_del_us2ds(ldp_global *g, ldp_attr * us, ldp_attr * ds)
4836 + if (!us || !ds) {
4837 + return;
4839 + if (ldp_attr_us_partof_ds(us, ds) == MPLS_BOOL_TRUE) {
4840 + us->ds_attr = NULL;
4841 + MPLS_REFCNT_RELEASE2(g, ds, ldp_attr_delete);
4842 + MPLS_LIST_REMOVE(&ds->us_attr_root, us, _ds_attr);
4843 + MPLS_REFCNT_RELEASE2(g, us, ldp_attr_delete);
4844 + } else {
4845 + MPLS_ASSERT(0);
4849 +void ldp_attr_add_fec(ldp_attr *a, ldp_fec *fec) {
4850 + MPLS_ASSERT(a && fec);
4851 + MPLS_REFCNT_HOLD(fec);
4852 + a->fec = fec;
4855 +void ldp_attr_del_fec(ldp_global *g, ldp_attr *a) {
4856 + MPLS_ASSERT(a);
4857 + if (a->fec) {
4858 + MPLS_REFCNT_RELEASE2(g, a->fec, ldp_fec_delete);
4859 + a->fec = NULL;
4863 +void ldp_attr_add_us2ds(ldp_attr * us, ldp_attr * ds)
4866 + if (!us || !ds) {
4867 + return;
4869 + if (ldp_attr_us_partof_ds(us, ds) == MPLS_BOOL_TRUE) {
4870 + return;
4872 + MPLS_REFCNT_HOLD(us);
4873 + MPLS_LIST_ADD_TAIL(&ds->us_attr_root, us, _ds_attr, ldp_attr);
4874 + MPLS_REFCNT_HOLD(ds);
4875 + us->ds_attr = ds;
4878 +void ldp_attr_action_callback(mpls_timer_handle timer, void *extra,
4879 + mpls_cfg_handle g)
4883 +ldp_attr *ldp_attr_find_downstream_state_any2(ldp_global * g, ldp_fec * f,
4884 + ldp_lsp_state state)
4886 + ldp_attr *attr = NULL;
4887 + ldp_fs *fs = NULL;
4889 + fs = MPLS_LIST_HEAD(&f->fs_root_ds);
4890 + while (fs != NULL) {
4891 + attr = MPLS_LIST_HEAD(&fs->attr_root);
4892 + while (attr != NULL) {
4893 + if (attr->state == state) {
4894 + return attr;
4896 + attr = MPLS_LIST_NEXT(&fs->attr_root, attr, _fs);
4898 + fs = MPLS_LIST_NEXT(&f->fs_root_ds, fs, _fec);
4900 + return NULL;
4903 +ldp_attr *ldp_attr_find_downstream_state_any(ldp_global * g, mpls_fec * f,
4904 + ldp_lsp_state state)
4906 + ldp_fec *fnode = _ldp_attr_get_fec2(g, f, MPLS_BOOL_FALSE);
4908 + if (!fnode) {
4909 + return NULL;
4912 + return ldp_attr_find_downstream_state_any2(g, fnode, state);
4915 +ldp_attr *ldp_attr_find_upstream_state_any2(ldp_global * g, ldp_fec * f,
4916 + ldp_lsp_state state)
4918 + ldp_attr *attr = NULL;
4919 + ldp_fs *fs = NULL;
4921 + fs = MPLS_LIST_HEAD(&f->fs_root_us);
4922 + while (fs != NULL) {
4923 + attr = MPLS_LIST_HEAD(&fs->attr_root);
4924 + while (attr != NULL) {
4925 + if (attr->state == state) {
4926 + return attr;
4928 + attr = MPLS_LIST_NEXT(&fs->attr_root, attr, _fs);
4930 + fs = MPLS_LIST_NEXT(&f->fs_root_us, fs, _fec);
4932 + return NULL;
4935 +ldp_attr *ldp_attr_find_upstream_state_any(ldp_global * g, mpls_fec * f,
4936 + ldp_lsp_state state)
4938 + ldp_fec *fnode = _ldp_attr_get_fec2(g, f, MPLS_BOOL_FALSE);
4940 + if (!fnode) {
4941 + return NULL;
4944 + return ldp_attr_find_upstream_state_any2(g, fnode, state);
4947 +static ldp_attr *_ldp_attr_find_downstream_state(ldp_attr_list *ds_list,
4948 + ldp_lsp_state state)
4950 + if (ds_list != NULL) {
4951 + ldp_attr *ds_attr = MPLS_LIST_HEAD(ds_list);
4953 + while (ds_attr != NULL) {
4954 + if (ds_attr->state == state) {
4955 + return ds_attr;
4957 + ds_attr = MPLS_LIST_NEXT(ds_list, ds_attr, _fs);
4960 + return NULL;
4963 +ldp_attr *ldp_attr_find_downstream_state2(ldp_global * g, ldp_session * s,
4964 + ldp_fec * f, ldp_lsp_state state)
4966 + ldp_attr_list *ds_list = ldp_attr_find_downstream_all2(g, s, f);
4967 + return _ldp_attr_find_downstream_state(ds_list, state);
4970 +ldp_attr *ldp_attr_find_downstream_state(ldp_global * g, ldp_session * s,
4971 + mpls_fec * f, ldp_lsp_state state)
4973 + ldp_attr_list *ds_list = ldp_attr_find_downstream_all(g, s, f);
4974 + return _ldp_attr_find_downstream_state(ds_list, state);
4977 +static ldp_attr *_ldp_attr_find_upstream_state(ldp_attr_list *us_list,
4978 + ldp_lsp_state state)
4980 + if (us_list != NULL) {
4981 + ldp_attr *us_attr = MPLS_LIST_HEAD(us_list);
4983 + while (us_attr != NULL) {
4984 + if (us_attr->state == state) {
4985 + return us_attr;
4987 + us_attr = MPLS_LIST_NEXT(us_list, us_attr, _fs);
4990 + return NULL;
4993 +ldp_attr *ldp_attr_find_upstream_state2(ldp_global * g, ldp_session * s,
4994 + ldp_fec * f, ldp_lsp_state state)
4996 + ldp_attr_list *us_list = ldp_attr_find_upstream_all2(g, s, f);
4997 + return _ldp_attr_find_upstream_state(us_list, state);
5000 +ldp_attr *ldp_attr_find_upstream_state(ldp_global * g, ldp_session * s,
5001 + mpls_fec * f, ldp_lsp_state state)
5003 + ldp_attr_list *us_list = ldp_attr_find_upstream_all(g, s, f);
5004 + return _ldp_attr_find_upstream_state(us_list, state);
5007 +void ldp_attr_remove_complete(ldp_global * g, ldp_attr * attr,
5008 + mpls_bool complete)
5010 + ldp_session *session = attr->session;
5011 + ldp_outlabel *out = NULL;
5012 + ldp_inlabel *in = NULL;
5013 + ldp_attr *us_temp = NULL;
5014 + mpls_fec fec;
5015 + int i;
5017 + switch (attr->state) {
5018 + case LDP_LSP_STATE_MAP_RECV:
5019 + if (attr->ingress == MPLS_BOOL_TRUE) {
5020 + out = attr->outlabel;
5021 + MPLS_ASSERT(out != NULL);
5022 + while ((in = MPLS_LIST_HEAD(&out->inlabel_root)) != NULL) {
5023 + ldp_inlabel_del_outlabel(g, in);
5026 + if (out->merge_count > 0) {
5027 + for (i = 0; i < attr->fecTlv.numberFecElements; i++) {
5028 + fec_tlv2mpls_fec(&attr->fecTlv, i, &fec);
5029 + out->merge_count--;
5030 +#if MPLS_USE_LSR
5032 + lsr_ftn ftn;
5033 + memcpy(&ftn.fec, &fec, sizeof(mpls_fec));
5034 + ftn.outsegment_index = out->info.handle;
5035 + lsr_cfg_ftn_set2(g->lsr_handle, &ftn, LSR_CFG_DEL);
5037 +#else
5038 + mpls_mpls_fec2out_del(g->mpls_handle, &fec, &out->info);
5039 +#endif
5042 + MPLS_ASSERT(out->merge_count == 0);
5043 + ldp_attr_del_outlabel(g, attr);
5044 + ldp_session_del_outlabel(g, session, out);
5046 + while ((us_temp = MPLS_LIST_HEAD(&attr->us_attr_root)) != NULL) {
5047 + ldp_attr_del_us2ds(g, us_temp, attr);
5049 + ldp_attr_delete_downstream(g, session, attr);
5050 + break;
5051 + case LDP_LSP_STATE_MAP_SENT:
5052 + in = attr->inlabel;
5053 + out = in->outlabel;
5055 + if (in->reuse_count == 1 && out) {
5056 + ldp_inlabel_del_outlabel(g, in);
5058 + ldp_attr_del_inlabel(g, attr);
5059 + ldp_attr_delete_upstream(g, session, attr);
5060 + ldp_attr_del_us2ds(g, attr, attr->ds_attr);
5061 + ldp_session_del_inlabel(g, session, in);
5062 + break;
5063 + case LDP_LSP_STATE_ABORT_SENT:
5064 + case LDP_LSP_STATE_NOTIF_SENT:
5065 + case LDP_LSP_STATE_REQ_RECV:
5066 + case LDP_LSP_STATE_WITH_SENT:
5067 + case LDP_LSP_STATE_NO_LABEL_RESOURCE_SENT:
5069 + ldp_attr_del_us2ds(g, attr, attr->ds_attr);
5070 + ldp_attr_delete_upstream(g, session, attr);
5071 + break;
5073 + case LDP_LSP_STATE_ABORT_RECV:
5074 + case LDP_LSP_STATE_NOTIF_RECV:
5075 + case LDP_LSP_STATE_REQ_SENT:
5076 + case LDP_LSP_STATE_WITH_RECV:
5077 + case LDP_LSP_STATE_NO_LABEL_RESOURCE_RECV:
5079 + while ((us_temp = MPLS_LIST_HEAD(&attr->us_attr_root)) != NULL) {
5080 + ldp_attr_del_us2ds(g, us_temp, attr);
5082 + ldp_attr_delete_downstream(g, session, attr);
5083 + break;
5088 +ldp_attr *ldp_attr_create(ldp_global *g, mpls_fec * fec)
5090 + ldp_attr *a = (ldp_attr *) mpls_malloc(sizeof(ldp_attr));
5092 + if (a != NULL) {
5093 + memset(a, 0, sizeof(ldp_attr));
5094 + MPLS_LIST_ELEM_INIT(a, _session);
5095 + MPLS_LIST_ELEM_INIT(a, _global);
5096 + MPLS_LIST_ELEM_INIT(a, _fs);
5097 + MPLS_LIST_INIT(&a->us_attr_root, ldp_attr);
5098 + MPLS_REFCNT_INIT(a, 0);
5099 + a->index = _ldp_attr_get_next_index();
5100 + a->in_tree = MPLS_BOOL_FALSE;
5101 + a->ingress = MPLS_BOOL_FALSE;
5102 + a->filtered = MPLS_BOOL_FALSE;
5104 + if (fec != NULL) {
5105 + mpls_fec2fec_tlv(fec, &a->fecTlv, 0);
5106 + a->fecTlv.numberFecElements = 1;
5107 + a->fecTlvExists = 1;
5109 + _ldp_global_add_attr(g, a);
5111 + return a;
5114 +void ldp_attr_delete(ldp_global *g, ldp_attr * a)
5116 + LDP_PRINT(g->user_data, "attr delete: %p", a);
5117 + MPLS_REFCNT_ASSERT(a, 0);
5118 + MPLS_ASSERT(a->in_tree == MPLS_BOOL_FALSE);
5119 + _ldp_global_del_attr(g, a);
5120 + mpls_free(a);
5123 +void ldp_attr2ldp_attr(ldp_attr * a, ldp_attr * b, uint32_t flag)
5125 + if (a->fecTlvExists && flag & LDP_ATTR_FEC) {
5126 + memcpy(&b->fecTlv, &a->fecTlv, sizeof(mplsLdpFecTlv_t));
5127 + b->fecTlvExists = 1;
5129 + if (a->genLblTlvExists && flag & LDP_ATTR_LABEL) {
5130 + memcpy(&b->genLblTlv, &a->genLblTlv, sizeof(mplsLdpGenLblTlv_t));
5131 + b->genLblTlvExists = 1;
5132 + } else if (a->atmLblTlvExists && flag & LDP_ATTR_LABEL) {
5133 + memcpy(&b->atmLblTlv, &a->atmLblTlv, sizeof(mplsLdpAtmLblTlv_t));
5134 + b->atmLblTlvExists = 1;
5135 + } else if (a->frLblTlvExists && flag & LDP_ATTR_LABEL) {
5136 + memcpy(&b->frLblTlv, &a->frLblTlv, sizeof(mplsLdpFrLblTlv_t));
5137 + b->frLblTlvExists = 1;
5139 + if (a->hopCountTlvExists && flag & LDP_ATTR_HOPCOUNT) {
5140 + memcpy(&b->hopCountTlv, &a->hopCountTlv, sizeof(mplsLdpHopTlv_t));
5141 + b->hopCountTlvExists = 1;
5143 + if (a->pathVecTlvExists && flag & LDP_ATTR_PATH) {
5144 + memcpy(&b->pathVecTlv, &a->pathVecTlv, sizeof(mplsLdpPathTlv_t));
5145 + b->pathVecTlvExists = 1;
5147 + if (a->lblMsgIdTlvExists && flag & LDP_ATTR_MSGID) {
5148 + memcpy(&b->lblMsgIdTlv, &a->lblMsgIdTlv, sizeof(mplsLdpLblMsgIdTlv_t));
5149 + b->lblMsgIdTlvExists = 1;
5151 + if (a->lspidTlvExists && flag & LDP_ATTR_LSPID) {
5152 + memcpy(&b->lspidTlv, &a->lspidTlv, sizeof(mplsLdpLspIdTlv_t));
5153 + b->lspidTlvExists = 1;
5155 + if (a->trafficTlvExists && flag & LDP_ATTR_TRAFFIC) {
5156 + memcpy(&b->trafficTlv, &a->trafficTlv, sizeof(mplsLdpTrafficTlv_t));
5157 + b->trafficTlvExists = 1;
5161 +mpls_return_enum ldp_attr_add_inlabel(ldp_global *g, ldp_attr * a, ldp_inlabel * i)
5163 + if (a && i) {
5164 + MPLS_REFCNT_HOLD(i);
5165 + a->inlabel = i;
5166 + _ldp_inlabel_add_attr(g, i, a);
5167 + return MPLS_SUCCESS;
5169 + return MPLS_FAILURE;
5172 +mpls_return_enum ldp_attr_del_inlabel(ldp_global *g, ldp_attr * a)
5174 + if (a && a->inlabel) {
5175 + _ldp_inlabel_del_attr(g, a->inlabel, a);
5176 + MPLS_REFCNT_RELEASE2(g, a->inlabel, ldp_inlabel_delete);
5177 + a->inlabel = NULL;
5178 + return MPLS_SUCCESS;
5180 + return MPLS_FAILURE;
5183 +mpls_return_enum ldp_attr_add_outlabel(ldp_attr * a, ldp_outlabel * o)
5185 + if (a && o) {
5186 + MPLS_REFCNT_HOLD(o);
5187 + a->outlabel = o;
5188 + _ldp_outlabel_add_attr(o, a);
5189 + return MPLS_SUCCESS;
5191 + return MPLS_FAILURE;
5194 +mpls_return_enum ldp_attr_del_outlabel(ldp_global * g, ldp_attr * a)
5196 + if (a && a->outlabel) {
5197 + _ldp_outlabel_del_attr(g, a->outlabel);
5198 + MPLS_REFCNT_RELEASE2(g, a->outlabel, ldp_outlabel_delete);
5199 + a->outlabel = NULL;
5200 + return MPLS_SUCCESS;
5202 + return MPLS_FAILURE;
5205 +mpls_return_enum ldp_attr_add_session(ldp_attr * a, ldp_session * s)
5207 + if (a && s) {
5208 + MPLS_REFCNT_HOLD(s);
5209 + a->session = s;
5210 + _ldp_session_add_attr(s, a);
5211 + return MPLS_SUCCESS;
5213 + return MPLS_FAILURE;
5216 +mpls_return_enum ldp_attr_del_session(ldp_global *g, ldp_attr * a)
5218 + if (a && a->session) {
5219 + _ldp_session_del_attr(g, a->session, a);
5220 + MPLS_REFCNT_RELEASE(a->session, ldp_session_delete);
5221 + a->session = NULL;
5222 + return MPLS_SUCCESS;
5224 + return MPLS_FAILURE;
5227 +mpls_bool ldp_attr_is_equal(ldp_attr * a, ldp_attr * b, uint32_t flag)
5229 + if (flag & LDP_ATTR_LABEL) {
5230 + if (a->genLblTlvExists && b->genLblTlvExists) {
5231 + if (a->genLblTlv.label != b->genLblTlv.label) {
5232 + return MPLS_BOOL_FALSE;
5234 + } else if (a->atmLblTlvExists && b->atmLblTlvExists) {
5235 + if (a->atmLblTlv.flags.flags.vpi != b->atmLblTlv.flags.flags.vpi ||
5236 + a->atmLblTlv.vci != b->atmLblTlv.vci) {
5237 + return MPLS_BOOL_FALSE;
5239 + } else if (a->frLblTlvExists && b->frLblTlvExists) {
5240 + if (a->frLblTlv.flags.flags.len != b->frLblTlv.flags.flags.len ||
5241 + a->frLblTlv.flags.flags.dlci != b->frLblTlv.flags.flags.dlci) {
5242 + return MPLS_BOOL_FALSE;
5244 + } else {
5245 + return MPLS_BOOL_FALSE;
5248 + if (flag & LDP_ATTR_HOPCOUNT) {
5249 + if (a->hopCountTlvExists && b->hopCountTlvExists) {
5250 + if (a->hopCountTlv.hcValue != b->hopCountTlv.hcValue) {
5251 + return MPLS_BOOL_FALSE;
5253 + } else {
5254 + if (a->hopCountTlvExists != b->hopCountTlvExists) {
5255 + return MPLS_BOOL_FALSE;
5259 + if (flag & LDP_ATTR_PATH) {
5260 + int i;
5262 + if (a->pathVecTlvExists && b->pathVecTlvExists) {
5263 + for (i = 0; i < MPLS_MAXHOPSNUMBER; i++) {
5264 + if (a->pathVecTlv.lsrId[i] != b->pathVecTlv.lsrId[i]) {
5265 + return MPLS_BOOL_FALSE;
5268 + } else {
5269 + if (a->hopCountTlvExists != b->hopCountTlvExists) {
5270 + return MPLS_BOOL_FALSE;
5274 + if (flag & LDP_ATTR_FEC) {
5275 + int i;
5277 + if (a->fecTlvExists && b->fecTlvExists) {
5278 + if (a->fecTlv.numberFecElements != b->fecTlv.numberFecElements) {
5279 + return MPLS_BOOL_FALSE;
5281 + for (i = 0; i < a->fecTlv.numberFecElements; i++) {
5282 + if (a->fecTlv.fecElemTypes[i] != b->fecTlv.fecElemTypes[i]) {
5283 + return MPLS_BOOL_FALSE;
5285 + switch (a->fecTlv.fecElemTypes[i]) {
5286 + case MPLS_CRLSP_FEC:
5287 + case MPLS_WC_FEC:
5288 + /* nothing of interest to compare */
5289 + break;
5290 + case MPLS_PREFIX_FEC:
5291 + case MPLS_HOSTADR_FEC:
5292 + if (a->fecTlv.fecElArray[i].addressEl.addressFam !=
5293 + b->fecTlv.fecElArray[i].addressEl.addressFam ||
5294 + a->fecTlv.fecElArray[i].addressEl.preLen !=
5295 + b->fecTlv.fecElArray[i].addressEl.preLen ||
5296 + a->fecTlv.fecElArray[i].addressEl.address !=
5297 + b->fecTlv.fecElArray[i].addressEl.address) {
5298 + return MPLS_BOOL_FALSE;
5300 + break;
5301 + default:
5302 + MPLS_ASSERT(0);
5305 + } else {
5306 + return MPLS_BOOL_FALSE;
5309 + if (flag & LDP_ATTR_MSGID) {
5310 + if (a->lblMsgIdTlvExists && b->lblMsgIdTlvExists) {
5311 + if (a->lblMsgIdTlv.msgId != b->lblMsgIdTlv.msgId) {
5312 + return MPLS_BOOL_FALSE;
5314 + } else {
5315 + return MPLS_BOOL_FALSE;
5318 + if (flag & LDP_ATTR_LSPID) {
5319 + if (a->lspidTlvExists && b->lspidTlvExists) {
5320 + if (a->lspidTlv.localCrlspId != b->lspidTlv.localCrlspId ||
5321 + a->lspidTlv.routerId != b->lspidTlv.routerId) {
5322 + return MPLS_BOOL_FALSE;
5324 + } else {
5325 + return MPLS_BOOL_FALSE;
5328 + if (flag & LDP_ATTR_TRAFFIC) {
5330 + return MPLS_BOOL_TRUE;
5333 +mpls_return_enum ldp_attr_insert_upstream2(ldp_global * g, ldp_session * s,
5334 + ldp_attr * a, ldp_fec *f)
5336 + ldp_fs *fs = NULL;
5337 + mpls_return_enum retval;
5339 + MPLS_ASSERT(g && s && a && (a->in_tree == MPLS_BOOL_FALSE) && f);
5341 + /* find the upstream fs for this session */
5342 + if ((fs = _ldp_fec_find_fs_us(f, s, MPLS_BOOL_TRUE)) == NULL) {
5343 + /* this session isn't in the list and cannot be added */
5344 + return MPLS_FAILURE;
5347 + ldp_attr_add_session(a, s);
5348 + ldp_attr_add_fec(a, f);
5350 + retval = _ldp_fs_add_attr(fs, a);
5351 + a->in_tree = MPLS_BOOL_TRUE;
5352 + return retval;
5355 +mpls_return_enum ldp_attr_insert_upstream(ldp_global * g, ldp_session * s,
5356 + ldp_attr * a)
5358 + ldp_fec *fnode = NULL;
5360 + MPLS_ASSERT(g && s && a && (a->in_tree == MPLS_BOOL_FALSE));
5362 + if ((fnode = _ldp_attr_get_fec(g, a, MPLS_BOOL_TRUE)) == NULL) {
5363 + /* we couldn't get/add a node from/to the tree! */
5364 + return MPLS_FAILURE;
5367 + return ldp_attr_insert_upstream2(g, s, a, fnode);
5370 +mpls_return_enum ldp_attr_insert_downstream2(ldp_global * g, ldp_session * s,
5371 + ldp_attr * a, ldp_fec *f)
5373 + ldp_fs *fs = NULL;
5374 + mpls_return_enum retval;
5376 + MPLS_ASSERT(g && s && a && (a->in_tree == MPLS_BOOL_FALSE) && f);
5378 + /* find the downstream fs for this session */
5379 + if ((fs = _ldp_fec_find_fs_ds(f, s, MPLS_BOOL_TRUE)) == NULL) {
5380 + /* this session isn't in the list and cannot be added */
5381 + return MPLS_FAILURE;
5384 + ldp_attr_add_session(a, s);
5385 + ldp_attr_add_fec(a, f);
5387 + retval = _ldp_fs_add_attr(fs, a);
5388 + a->in_tree = MPLS_BOOL_TRUE;
5389 + return retval;
5392 +mpls_return_enum ldp_attr_insert_downstream(ldp_global * g, ldp_session * s,
5393 + ldp_attr * a)
5395 + ldp_fec *fnode = NULL;
5397 + MPLS_ASSERT(g && s && a && (a->in_tree == MPLS_BOOL_FALSE));
5399 + if ((fnode = _ldp_attr_get_fec(g, a, MPLS_BOOL_TRUE)) == NULL) {
5400 + /* we couldn't get/add a node from/to the tree! */
5401 + return MPLS_FAILURE;
5404 + return ldp_attr_insert_downstream2(g, s, a, fnode);
5407 +ldp_attr_list *ldp_attr_find_upstream_all2(ldp_global * g, ldp_session * s,
5408 + ldp_fec * f)
5410 + ldp_fs *fs = NULL;
5412 + MPLS_ASSERT(f && g);
5414 + if (!s) {
5415 + return NULL;
5418 + /* find the upstream fs for this session */
5419 + if ((fs = _ldp_fec_find_fs_us(f, s, MPLS_BOOL_FALSE)) == NULL) {
5420 + /* this session isn't in the list */
5421 + return NULL;
5423 + return &fs->attr_root;
5426 +ldp_attr_list *ldp_attr_find_upstream_all(ldp_global * g, ldp_session * s,
5427 + mpls_fec * f)
5429 + ldp_fec *fnode = NULL;
5431 + MPLS_ASSERT(f && g);
5433 + if (!s) {
5434 + return NULL;
5437 + if ((fnode = _ldp_attr_get_fec2(g, f, MPLS_BOOL_FALSE)) == NULL) {
5438 + /* we couldn't get the node from the tree! */
5439 + return NULL;
5442 + return ldp_attr_find_upstream_all2(g, s, fnode);
5445 +ldp_attr_list *ldp_attr_find_downstream_all2(ldp_global * g, ldp_session * s,
5446 + ldp_fec * f)
5448 + ldp_fs *fs = NULL;
5450 + MPLS_ASSERT(f && g);
5452 + if (!s) {
5453 + return NULL;
5456 + /* find the downstream fs for this session */
5457 + if ((fs = _ldp_fec_find_fs_ds(f, s, MPLS_BOOL_FALSE)) == NULL) {
5458 + /* this session isn't in the list */
5459 + return NULL;
5461 + return &fs->attr_root;
5464 +ldp_attr_list *ldp_attr_find_downstream_all(ldp_global * g, ldp_session * s,
5465 + mpls_fec * f)
5467 + ldp_fec *fnode = NULL;
5469 + MPLS_ASSERT(f && g);
5471 + if (!s) {
5472 + return NULL;
5475 + if ((fnode = _ldp_attr_get_fec2(g, f, MPLS_BOOL_FALSE)) == NULL) {
5476 + /* we couldn't get the node from the tree! */
5477 + return NULL;
5480 + return ldp_attr_find_downstream_all2(g, s, fnode);
5483 +void ldp_attr_delete_upstream(ldp_global * g, ldp_session * s, ldp_attr * a)
5485 + ldp_fec *fnode = NULL;
5486 + ldp_fs *fs = NULL;
5488 + MPLS_ASSERT(a->in_tree == MPLS_BOOL_TRUE);
5490 + MPLS_REFCNT_HOLD(a);
5492 + /* find the fec node in the tree */
5493 + if ((fnode = _ldp_attr_get_fec(g, a, MPLS_BOOL_FALSE))) {
5494 + /* find the upstream fs for this session, on the fec */
5495 + if ((fs = _ldp_fec_find_fs_us(fnode, s, MPLS_BOOL_FALSE))) {
5496 + /* remove this attr from the fs, if this was the last
5497 + * attr on the fs, then remove the fs from the fec node
5498 + */
5499 + if (_ldp_fs_del_attr(g, fs, a) == MPLS_BOOL_TRUE) {
5500 + _ldp_fec_del_fs_us(fnode, fs);
5505 + ldp_attr_del_session(g, a);
5506 + ldp_attr_del_fec(g, a);
5508 + a->in_tree = MPLS_BOOL_FALSE;
5509 + MPLS_REFCNT_RELEASE2(g, a, ldp_attr_delete);
5512 +void ldp_attr_delete_downstream(ldp_global * g, ldp_session * s, ldp_attr * a)
5514 + ldp_fec *fnode = NULL;
5515 + ldp_fs *fs = NULL;
5517 + MPLS_ASSERT(a->in_tree == MPLS_BOOL_TRUE);
5519 + MPLS_REFCNT_HOLD(a);
5520 + /* see ldp_attr_delete_upstream for more info */
5521 + if ((fnode = _ldp_attr_get_fec(g, a, MPLS_BOOL_FALSE))) {
5522 + if ((fs = _ldp_fec_find_fs_ds(fnode, s, MPLS_BOOL_FALSE))) {
5523 + if (_ldp_fs_del_attr(g, fs, a) == MPLS_BOOL_TRUE) {
5524 + _ldp_fec_del_fs_ds(fnode, fs);
5529 + ldp_attr_del_session(g, a);
5530 + ldp_attr_del_fec(g, a);
5532 + a->in_tree = MPLS_BOOL_FALSE;
5533 + MPLS_REFCNT_RELEASE2(g, a, ldp_attr_delete);
5536 +void ldp_attr2mpls_label_struct(ldp_attr * a, mpls_label_struct * l)
5538 + if (a->genLblTlvExists) {
5539 + l->type = MPLS_LABEL_TYPE_GENERIC;
5540 + l->u.gen = a->genLblTlv.label;
5541 + } else if (a->atmLblTlvExists) {
5542 + l->type = MPLS_LABEL_TYPE_ATM;
5543 + l->u.atm.vpi = a->atmLblTlv.flags.flags.vpi;
5544 + l->u.atm.vci = a->atmLblTlv.vci;
5545 + } else if (a->frLblTlvExists) {
5546 + l->type = MPLS_LABEL_TYPE_FR;
5547 + l->u.fr.len = a->frLblTlv.flags.flags.len;
5548 + l->u.fr.dlci = a->frLblTlv.flags.flags.dlci;
5549 + } else {
5550 + MPLS_ASSERT(0);
5554 +void mpls_label_struct2ldp_attr(mpls_label_struct * l, ldp_attr * a)
5556 + switch (l->type) {
5557 + case MPLS_LABEL_TYPE_GENERIC:
5558 + a->genLblTlvExists = 1;
5559 + a->atmLblTlvExists = 0;
5560 + a->frLblTlvExists = 0;
5561 + a->genLblTlv.label = l->u.gen;
5562 + break;
5563 + case MPLS_LABEL_TYPE_ATM:
5564 + a->genLblTlvExists = 0;
5565 + a->atmLblTlvExists = 1;
5566 + a->frLblTlvExists = 0;
5567 + a->atmLblTlv.flags.flags.vpi = l->u.atm.vpi;
5568 + a->atmLblTlv.vci = l->u.atm.vci;
5569 + case MPLS_LABEL_TYPE_FR:
5570 + a->genLblTlvExists = 0;
5571 + a->atmLblTlvExists = 0;
5572 + a->frLblTlvExists = 1;
5573 + a->frLblTlv.flags.flags.len = l->u.fr.len;
5574 + a->frLblTlv.flags.flags.dlci = l->u.fr.dlci;
5575 + default:
5576 + MPLS_ASSERT(0);
5580 +#if 0
5581 +void ldp_attr2ldp_attr(ldp_attr * src, ldp_attr * dst, u_int32 flag)
5583 + if (flag & LDP_ATTR_FEC) {
5584 + memcpy(&dst->fecTlv, &src->fecTlv, sizeof(mplsLdpFecTlv_t));
5585 + dst->fecTlvExists = src->fecTlvExists;
5587 + if (flag & LDP_ATTR_LABEL) {
5588 + memcpy(&dst->genLblTlv, &src->genLblTlv, sizeof(mplsLdpGenLblTlv_t));
5589 + memcpy(&dst->atmLblTlv, &src->atmLblTlv, sizeof(mplsLdpAtmLblTlv_t));
5590 + memcpy(&dst->frLblTlv, &src->frLblTlv, sizeof(mplsLdpFrLblTlv_t));
5591 + dst->genLblTlvExists = src->genLblTlvExists
5592 + dst->atmLblTlvExists = src->atmLblTlvExists
5593 + dst->frLblTlvExists = src->frLblTlvExists}
5594 + if (flag & LDP_ATTR_HOPCOUNT) {
5595 + memcpy(&dst->hopCountTlv, &src->hopCountTlv, sizeof(mplsLdpHopTlv_t));
5596 + dst->hopCountTlvExists = src->hopCountTlvExists;
5598 + if (flag & LDP_ATTR_PATH) {
5599 + memcpy(&dst->pathVecTlv, &src->pathVecTlv, sizeof(mplsLdpPathTlv_t));
5600 + dst->pathVecTlvExists = src->pathVecTlvExists;
5602 + if (flag & LDP_ATTR_MSGID) {
5603 + memcpy(&dst->lblMsgIdTlv, &src->lblMsgIdTlv, sizeof(mplsLdpLblMsgIdTlv_t));
5604 + dst->lblMsgIdTlvExists = src->lblMsgIdTlvExists;
5606 + if (flag & LDP_ATTR_LSPID) {
5607 + memcpy(&dst->lspidTlv, &src->lspidTlv, sizeof(mplsLdpLspIdTlv_t));
5608 + dst->lspidTlvExists = src->lspidTlvExists;
5610 + if (flag & LDP_ATTR_TRAFFIC) {
5611 + memcpy(&dst->trafficTlv, &src->trafficTlv, sizeof(mplsLdpTrafficTlv_t));
5612 + dst->trafficTlvExists = src->trafficTlvExists;
5615 +#endif
5617 +ldp_fec *_ldp_attr_get_fec2(ldp_global * g, mpls_fec * f, mpls_bool flag)
5619 + ldp_fec *fnode = NULL;
5621 + if (!(fnode = ldp_fec_find(g,f))) {
5622 + if (flag == MPLS_BOOL_FALSE) {
5623 + return NULL;
5626 + /* this FEC doesn't exist in the tree yet, create one ... */
5627 + if (!(fnode = ldp_fec_create(g, f))) {
5628 + /* insert failed */
5629 + return NULL;
5632 + return fnode;
5635 +static ldp_fec *_ldp_attr_get_fec(ldp_global * g, ldp_attr * a, mpls_bool flag)
5637 + mpls_fec fec;
5639 + /* get FEC from attr */
5640 + fec_tlv2mpls_fec(&a->fecTlv, 0, &fec);
5641 + return _ldp_attr_get_fec2(g, &fec, flag);
5644 +static ldp_fs *_ldp_fec_add_fs_ds(ldp_fec * fec, ldp_session * s)
5646 + ldp_fs *fs = _ldp_fec_find_fs_ds(fec, s, MPLS_BOOL_FALSE);
5648 + if (fs == NULL) {
5649 + fs = _ldp_fs_create(s);
5650 + if (fs == NULL) {
5651 + return NULL;
5653 + MPLS_LIST_ADD_HEAD(&fec->fs_root_ds, fs, _fec, ldp_fs);
5655 + return fs;
5658 +static ldp_fs *_ldp_fec_add_fs_us(ldp_fec * fec, ldp_session * s)
5660 + ldp_fs *fs = _ldp_fec_find_fs_us(fec, s, MPLS_BOOL_FALSE);
5662 + if (fs == NULL) {
5663 + fs = _ldp_fs_create(s);
5664 + if (fs == NULL) {
5665 + return NULL;
5667 + MPLS_LIST_ADD_HEAD(&fec->fs_root_us, fs, _fec, ldp_fs);
5669 + return fs;
5672 +static ldp_fs *_ldp_fec_find_fs_us(ldp_fec * fec, ldp_session * s,
5673 + mpls_bool flag)
5675 + ldp_fs *fs = MPLS_LIST_HEAD(&fec->fs_root_us);
5677 + while (fs != NULL) {
5678 + if (fs->session->index == s->index) {
5679 + return fs;
5681 + fs = MPLS_LIST_NEXT(&fec->fs_root_us, fs, _fec);
5683 + if (flag == MPLS_BOOL_FALSE) {
5684 + return NULL;
5686 + return _ldp_fec_add_fs_us(fec, s);
5689 +static ldp_fs *_ldp_fec_find_fs_ds(ldp_fec * fec, ldp_session * s,
5690 + mpls_bool flag)
5692 + ldp_fs *fs = MPLS_LIST_HEAD(&fec->fs_root_ds);
5694 + while (fs != NULL) {
5695 + if (fs->session->index == s->index) {
5696 + return fs;
5698 + fs = MPLS_LIST_NEXT(&fec->fs_root_ds, fs, _fec);
5700 + if (flag == MPLS_BOOL_FALSE) {
5701 + return NULL;
5703 + return _ldp_fec_add_fs_ds(fec, s);
5706 +static void _ldp_fec_del_fs_us(ldp_fec * fec, ldp_fs * fs)
5708 + if (fs == NULL) {
5709 + return;
5711 + MPLS_LIST_REMOVE(&fec->fs_root_us, fs, _fec);
5712 + _ldp_fs_delete(fs);
5715 +static void _ldp_fec_del_fs_ds(ldp_fec * fec, ldp_fs * fs)
5717 + if (fs == NULL) {
5718 + return;
5720 + MPLS_LIST_REMOVE(&fec->fs_root_ds, fs, _fec);
5721 + _ldp_fs_delete(fs);
5724 +static ldp_fs *_ldp_fs_create(ldp_session * s)
5726 + ldp_fs *fs = (ldp_fs *) mpls_malloc(sizeof(ldp_fs));
5728 + if (fs != NULL) {
5729 + memset(fs, 0, sizeof(ldp_fs));
5730 + MPLS_LIST_INIT(&fs->attr_root, ldp_attr);
5731 + MPLS_LIST_ELEM_INIT(fs, _fec);
5732 + if (s != NULL) {
5733 + MPLS_REFCNT_HOLD(s);
5734 + fs->session = s;
5737 + return fs;
5740 +static void _ldp_fs_delete(ldp_fs * fs)
5742 + LDP_PRINT(NULL, "fs delete %p", fs);
5743 + if (fs->session != NULL) {
5744 + MPLS_REFCNT_RELEASE(fs->session, ldp_session_delete);
5746 + mpls_free(fs);
5749 +static ldp_attr *_ldp_fs_find_attr(ldp_fs * fs, ldp_attr * a)
5751 + ldp_attr *ptr = MPLS_LIST_HEAD(&fs->attr_root);
5753 + while (ptr != NULL) {
5754 + if (ldp_attr_is_equal(a, ptr, LDP_ATTR_LABEL | LDP_ATTR_FEC) == MPLS_BOOL_TRUE) {
5755 + return ptr;
5757 + ptr = MPLS_LIST_NEXT(&fs->attr_root, ptr, _fs);
5759 + return NULL;
5762 +static mpls_return_enum _ldp_fs_add_attr(ldp_fs * fs, ldp_attr * a)
5764 + ldp_attr *ptr = _ldp_fs_find_attr(fs, a);
5766 + MPLS_ASSERT(ptr == NULL);
5767 + MPLS_REFCNT_HOLD(a);
5768 + MPLS_LIST_ADD_HEAD(&fs->attr_root, a, _fs, ldp_attr);
5769 + return MPLS_SUCCESS;
5772 +static mpls_bool _ldp_fs_del_attr(ldp_global *g, ldp_fs * fs, ldp_attr * a)
5774 + ldp_attr *ptr = _ldp_fs_find_attr(fs, a);
5776 + if (ptr != NULL) {
5777 + MPLS_LIST_REMOVE(&fs->attr_root, ptr, _fs);
5778 + MPLS_REFCNT_RELEASE2(g, ptr, ldp_attr_delete);
5780 + if (MPLS_LIST_HEAD(&fs->attr_root) == NULL)
5781 + return MPLS_BOOL_TRUE;
5782 + return MPLS_BOOL_FALSE;
5785 +ldp_attr *ldp_attr_find_upstream_map_in_labelspace(ldp_fec *f, int labelspace)
5787 + ldp_fs *fs = MPLS_LIST_HEAD(&f->fs_root_us);
5789 + while (fs) {
5790 + ldp_attr *attr = MPLS_LIST_HEAD(&fs->attr_root);
5791 + while (attr) {
5792 + if (attr->state == LDP_LSP_STATE_MAP_SENT) {
5793 + if (attr->session->cfg_label_space == labelspace) {
5794 + return attr;
5797 + attr = MPLS_LIST_NEXT(&fs->attr_root, attr, _fs);
5799 + fs = MPLS_LIST_NEXT(&f->fs_root_us, fs, _fec);
5801 + return NULL;
5804 +static uint32_t _ldp_attr_get_next_index()
5806 + uint32_t retval = _ldp_attr_next_index;
5808 + _ldp_attr_next_index++;
5809 + if (retval > _ldp_attr_next_index) {
5810 + _ldp_attr_next_index = 1;
5812 + return retval;
5814 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_attr.h quagga-mpls/ldpd/ldp_attr.h
5815 --- quagga/ldpd/ldp_attr.h 1969-12-31 18:00:00.000000000 -0600
5816 +++ quagga-mpls/ldpd/ldp_attr.h 2006-10-16 22:39:55.000000000 -0500
5817 @@ -0,0 +1,91 @@
5820 + * Copyright (C) James R. Leu 2000
5821 + * jleu@mindspring.com
5823 + * This software is covered under the LGPL, for more
5824 + * info check out http://www.gnu.org/copyleft/lgpl.html
5825 + */
5827 +#ifndef _LDP_ATTR_H_
5828 +#define _LDP_ATTR_H_
5829 +#include "ldp_struct.h"
5831 +#define LDP_ATTR_LABEL 0x01
5832 +#define LDP_ATTR_HOPCOUNT 0x02
5833 +#define LDP_ATTR_PATH 0x04
5834 +#define LDP_ATTR_FEC 0x08
5835 +#define LDP_ATTR_MSGID 0x10
5836 +#define LDP_ATTR_LSPID 0x20
5837 +#define LDP_ATTR_TRAFFIC 0x40
5838 +#define LDP_ATTR_STATUS 0x80
5839 +#define LDP_ATTR_ALL 0xFF
5841 +extern void ldp_attr_action_callback(mpls_timer_handle timer, void *extra,
5842 + mpls_cfg_handle g);
5844 +extern void ldp_attr_add_fec(ldp_attr *a, ldp_fec *fec);
5845 +extern void ldp_attr_del_fec(ldp_global *g, ldp_attr *a);
5847 +extern void ldp_attr_add_us2ds(ldp_attr * us, ldp_attr * ds);
5848 +extern void ldp_attr_del_us2ds(ldp_global *g, ldp_attr * us, ldp_attr * ds);
5849 +extern mpls_bool ldp_attr_us_partof_ds(ldp_attr * us, ldp_attr * ds);
5850 +extern int ldp_attr_num_us2ds(ldp_attr * ds);
5852 +extern ldp_attr *ldp_attr_create(ldp_global * g, mpls_fec * fec);
5853 +extern void ldp_attr_delete(ldp_global * g, ldp_attr * a);
5854 +extern void ldp_attr2ldp_attr(ldp_attr * a, ldp_attr * b, uint32_t flag);
5855 +extern void ldp_attr_remove_complete(ldp_global * g, ldp_attr * attr, mpls_bool);
5857 +extern ldp_attr *ldp_attr_find_downstream_state2(ldp_global * g,ldp_session * s,
5858 + ldp_fec * f, ldp_lsp_state state);
5859 +extern ldp_attr *ldp_attr_find_downstream_state(ldp_global * g, ldp_session * s,
5860 + mpls_fec * f, ldp_lsp_state state);
5861 +extern ldp_attr *ldp_attr_find_upstream_state2(ldp_global * g, ldp_session * s,
5862 + ldp_fec * f, ldp_lsp_state state);
5863 +extern ldp_attr *ldp_attr_find_upstream_state(ldp_global * g, ldp_session * s,
5864 + mpls_fec * f, ldp_lsp_state state);
5866 +extern ldp_attr *ldp_attr_find_downstream_state_any2(ldp_global *g, ldp_fec *f,
5867 + ldp_lsp_state state);
5868 +extern ldp_attr *ldp_attr_find_downstream_state_any(ldp_global *g, mpls_fec *f,
5869 + ldp_lsp_state state);
5870 +extern ldp_attr *ldp_attr_find_upstream_state_any2(ldp_global * g, ldp_fec * f,
5871 + ldp_lsp_state state);
5872 +extern ldp_attr *ldp_attr_find_upstream_state_any(ldp_global * g, mpls_fec * f,
5873 + ldp_lsp_state state);
5874 +extern ldp_attr *ldp_attr_find_upstream_map_in_labelspace(ldp_fec *f,
5875 + int labelspace);
5878 +extern mpls_return_enum ldp_attr_del_outlabel(ldp_global * g,ldp_attr * a);
5879 +extern mpls_return_enum ldp_attr_add_outlabel(ldp_attr * a, ldp_outlabel * o);
5880 +extern mpls_return_enum ldp_attr_add_inlabel(ldp_global * g, ldp_attr * a, ldp_inlabel * i);
5881 +extern mpls_return_enum ldp_attr_del_inlabel(ldp_global * g,ldp_attr * a);
5882 +extern mpls_return_enum ldp_attr_add_session(ldp_attr * a, ldp_session * s);
5883 +extern mpls_return_enum ldp_attr_del_session(ldp_global *g, ldp_attr * a);
5885 +extern mpls_bool ldp_attr_is_equal(ldp_attr * a, ldp_attr * b, uint32_t flag);
5886 +extern ldp_attr_list *ldp_attr_find_upstream_all2(ldp_global * g,
5887 + ldp_session * s, ldp_fec * f);
5888 +extern ldp_attr_list *ldp_attr_find_upstream_all(ldp_global * g,
5889 + ldp_session * s, mpls_fec * f);
5890 +extern ldp_attr_list *ldp_attr_find_downstream_all2(ldp_global * g,
5891 + ldp_session * s, ldp_fec * f);
5892 +extern ldp_attr_list *ldp_attr_find_downstream_all(ldp_global * g,
5893 + ldp_session * s, mpls_fec * f);
5894 +extern void ldp_attr_delete_upstream(ldp_global *, ldp_session *, ldp_attr *);
5895 +extern void ldp_attr_delete_downstream(ldp_global *, ldp_session *, ldp_attr *);
5896 +extern mpls_return_enum ldp_attr_insert_upstream2(ldp_global *g,ldp_session *s,
5897 + ldp_attr * a, ldp_fec *f);
5898 +extern mpls_return_enum ldp_attr_insert_upstream(ldp_global *g, ldp_session *s,
5899 + ldp_attr * a);
5900 +extern mpls_return_enum ldp_attr_insert_downstream2(ldp_global * g,
5901 + ldp_session * s, ldp_attr * a, ldp_fec *f);
5902 +extern mpls_return_enum ldp_attr_insert_downstream(ldp_global * g,
5903 + ldp_session * s, ldp_attr * a);
5905 +extern void mpls_label_struct2ldp_attr(mpls_label_struct * l, ldp_attr * a);
5906 +extern void ldp_attr2mpls_label_struct(ldp_attr * a, mpls_label_struct * l);
5908 +#endif
5909 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_buf.c quagga-mpls/ldpd/ldp_buf.c
5910 --- quagga/ldpd/ldp_buf.c 1969-12-31 18:00:00.000000000 -0600
5911 +++ quagga-mpls/ldpd/ldp_buf.c 2008-03-24 20:22:28.000000000 -0500
5912 @@ -0,0 +1,471 @@
5915 + * Copyright (C) James R. Leu 2000
5916 + * jleu@mindspring.com
5918 + * This software is covered under the LGPL, for more
5919 + * info check out http://www.gnu.org/copyleft/lgpl.html
5920 + */
5922 +#include <stdio.h>
5923 +#include <netinet/in.h>
5924 +#include "ldp_struct.h"
5925 +#include "ldp_nortel.h"
5926 +#include "ldp_buf.h"
5927 +#include "ldp_mesg.h"
5928 +#include "mpls_mm_impl.h"
5929 +#include "mpls_trace_impl.h"
5930 +#include <errno.h>
5932 +int debug = 0;
5934 +ldp_buf *ldp_buf_create(int size)
5936 + ldp_buf *b = (ldp_buf *) mpls_malloc(sizeof(ldp_buf));
5937 + char *c = NULL;
5939 + if (!b) {
5940 + return NULL;
5942 + memset(b, 0 , sizeof(ldp_buf));
5943 + c = (char*) mpls_malloc(size);
5945 + if (!c) {
5946 + mpls_free(b);
5947 + return NULL;
5950 + memset(c, 0, size);
5952 + b->buffer = c;
5953 + b->total = size;
5954 + b->size = 0;
5955 + b->current_size = 0;
5956 + b->current = b->buffer;
5958 + return b;
5961 +void ldp_buf_delete(ldp_buf * b)
5963 + MPLS_ASSERT(b);
5964 + if (b->buffer)
5965 + mpls_free(b->buffer);
5966 + mpls_free(b);
5969 +void ldp_buf_dump(mpls_instance_handle handle, ldp_buf * b, int size)
5971 + unsigned char *buf = b->current;
5972 + int i;
5973 + int j = 0;
5975 + for (i = 0; i < size; i++) {
5976 + LDP_TRACE_OUT(handle, "%02x ", buf[i]);
5977 + j++;
5978 + if (j == 16) {
5979 + LDP_TRACE_OUT(handle, "\n");
5980 + j = 0;
5983 + LDP_TRACE_OUT(handle, "\n");
5986 +int ldp_encode_one_mesg(ldp_global * g, uint32_t lsraddr, int label_space,
5987 + ldp_buf * b, ldp_mesg * msg)
5989 + ldp_trace_flags type = LDP_TRACE_FLAG_INIT;
5991 + unsigned char *hdrBuf = b->buffer;
5992 + unsigned char *bodyBuf = hdrBuf + MPLS_LDP_HDRSIZE;
5994 + int bodyBuf_size = b->total - MPLS_LDP_HDRSIZE;
5995 + int hdrBuf_size = MPLS_LDP_HDRSIZE;
5997 + int hdr_size;
5998 + int body_size;
6000 + switch (msg->u.generic.flags.flags.msgType) {
6001 + case MPLS_INIT_MSGTYPE:
6002 + body_size = Mpls_encodeLdpInitMsg(&msg->u.init, bodyBuf, bodyBuf_size);
6003 + break;
6004 + case MPLS_NOT_MSGTYPE:
6005 + body_size = Mpls_encodeLdpNotMsg(&msg->u.notif, bodyBuf, bodyBuf_size);
6006 + break;
6007 + case MPLS_KEEPAL_MSGTYPE:
6008 + body_size =
6009 + Mpls_encodeLdpKeepAliveMsg(&msg->u.keep, bodyBuf, bodyBuf_size);
6010 + break;
6011 + case MPLS_HELLO_MSGTYPE:
6012 + body_size = Mpls_encodeLdpHelloMsg(&msg->u.hello, bodyBuf, bodyBuf_size);
6013 + break;
6014 + case MPLS_LBLREQ_MSGTYPE:
6015 + body_size =
6016 + Mpls_encodeLdpLblReqMsg(&msg->u.request, bodyBuf, bodyBuf_size);
6017 + break;
6018 + case MPLS_LBLMAP_MSGTYPE:
6019 + body_size = Mpls_encodeLdpLblMapMsg(&msg->u.map, bodyBuf, bodyBuf_size);
6020 + break;
6021 + case MPLS_ADDR_MSGTYPE:
6022 + case MPLS_ADDRWITH_MSGTYPE:
6023 + body_size = Mpls_encodeLdpAdrMsg(&msg->u.addr, bodyBuf, bodyBuf_size);
6024 + break;
6025 + case MPLS_LBLWITH_MSGTYPE:
6026 + case MPLS_LBLREL_MSGTYPE:
6027 + body_size =
6028 + Mpls_encodeLdpLbl_W_R_Msg(&msg->u.release, bodyBuf, bodyBuf_size);
6029 + break;
6030 + case MPLS_LBLABORT_MSGTYPE:
6031 + body_size =
6032 + Mpls_encodeLdpLblAbortMsg(&msg->u.abort, bodyBuf, bodyBuf_size);
6033 + break;
6034 + default:
6035 + MPLS_ASSERT(0);
6038 + if (body_size < 0) {
6039 + return body_size;
6042 + msg->header.protocolVersion = 1;
6043 + msg->header.pduLength = body_size;
6044 + msg->header.pduLength = body_size + MPLS_LDPIDLEN;
6045 + msg->header.lsrAddress = lsraddr;
6046 + msg->header.labelSpace = label_space;
6048 + switch (msg->u.generic.flags.flags.msgType) {
6049 + case MPLS_INIT_MSGTYPE:
6050 + type = LDP_TRACE_FLAG_INIT;
6051 + LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
6052 + printHeader(g->user_data, &msg->header),
6053 + printInitMsg(g->user_data, &msg->u.init));
6054 + break;
6055 + case MPLS_NOT_MSGTYPE:
6056 + type = LDP_TRACE_FLAG_NOTIF;
6057 + LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_NOTIF,
6058 + printHeader(g->user_data, &msg->header),
6059 + printNotMsg(g->user_data, &msg->u.notif));
6060 + break;
6061 + case MPLS_KEEPAL_MSGTYPE:
6062 + type = LDP_TRACE_FLAG_PERIODIC;
6063 + LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_PERIODIC,
6064 + printHeader(g->user_data, &msg->header),
6065 + printKeepAliveMsg(g->user_data, &msg->u.keep));
6066 + break;
6067 + case MPLS_HELLO_MSGTYPE:
6068 + type = LDP_TRACE_FLAG_PERIODIC;
6069 + LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_PERIODIC,
6070 + printHeader(g->user_data, &msg->header),
6071 + printHelloMsg(g->user_data, &msg->u.hello));
6072 + break;
6073 + case MPLS_LBLREQ_MSGTYPE:
6074 + type = LDP_TRACE_FLAG_LABEL;
6075 + LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
6076 + printHeader(g->user_data, &msg->header),
6077 + printLlbReqMsg(g->user_data, &msg->u.request));
6078 + break;
6079 + case MPLS_LBLMAP_MSGTYPE:
6080 + type = LDP_TRACE_FLAG_LABEL;
6081 + LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
6082 + printHeader(g->user_data, &msg->header),
6083 + printLlbMapMsg(g->user_data, &msg->u.map));
6084 + break;
6085 + case MPLS_ADDR_MSGTYPE:
6086 + case MPLS_ADDRWITH_MSGTYPE:
6087 + type = LDP_TRACE_FLAG_ADDRESS;
6088 + LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_ADDRESS,
6089 + printHeader(g->user_data, &msg->header),
6090 + printAddressMsg(g->user_data, &msg->u.addr));
6091 + break;
6092 + case MPLS_LBLWITH_MSGTYPE:
6093 + case MPLS_LBLREL_MSGTYPE:
6094 + type = LDP_TRACE_FLAG_LABEL;
6095 + LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
6096 + printHeader(g->user_data, &msg->header),
6097 + printLbl_W_R_Msg(g->user_data, &msg->u.release));
6098 + break;
6099 + case MPLS_LBLABORT_MSGTYPE:
6100 + type = LDP_TRACE_FLAG_LABEL;
6101 + LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
6102 + printHeader(g->user_data, &msg->header),
6103 + printLlbAbortMsg(g->user_data, &msg->u.abort));
6104 + break;
6107 + if ((hdr_size =
6108 + Mpls_encodeLdpMsgHeader(&msg->header, hdrBuf, hdrBuf_size)) < 0) {
6109 + return hdr_size;
6112 + b->current_size = hdr_size + body_size;
6113 + b->current = b->buffer;
6114 + b->size = b->current_size;
6116 + LDP_DUMP_PKT(g->user_data, type, MPLS_TRACE_STATE_SEND,
6117 + ldp_buf_dump(g->user_data, b, b->size));
6119 + return b->size;
6122 +mpls_return_enum ldp_decode_header(ldp_global * g, ldp_buf * b, ldp_mesg * msg)
6124 + int encodedSize;
6126 + LDP_ENTER(g->user_data, "ldp_decode_header");
6128 + encodedSize =
6129 + Mpls_decodeLdpMsgHeader(&msg->header, b->current, b->current_size);
6131 + if (encodedSize < 0) {
6132 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_PACKET,
6133 + "Failed while decoding HEADER:%d\n", encodedSize);
6134 + LDP_EXIT(g->user_data, "ldp_decode_header - failure");
6135 + return MPLS_FAILURE;
6138 + LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_PACKET, MPLS_TRACE_STATE_RECV,
6139 + ldp_buf_dump(g->user_data, b, encodedSize));
6141 + b->current_size -= encodedSize;
6142 + b->current += encodedSize;
6144 + LDP_EXIT(g->user_data, "ldp_decode_header");
6145 + return MPLS_SUCCESS;
6148 +int ldp_decode_one_mesg(ldp_global * g, ldp_buf * b, ldp_mesg * msg)
6150 + int max_mesg_size;
6151 + int encodedSize = 0;
6152 + u_short type = 0;
6153 + int mesgSize = 0;
6155 + MPLS_ASSERT(b);
6157 + LDP_ENTER(g->user_data, "ldp_decode_one_mesg");
6159 + if (msg->header.pduLength > (b->size - 4)) {
6160 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
6161 + LDP_TRACE_FLAG_PACKET, "Buffer too small. Decoding failed\n");
6162 + LDP_EXIT(g->user_data, "ldp_decode_one_mesg - failure");
6163 + return MPLS_FAILURE;
6166 + max_mesg_size = b->current_size;
6168 + /* found the message type */
6169 + memcpy((u_char *) & type, b->current, 2);
6170 + type = ntohs(type) & 0x7fff; /* ignore the U bit for now */
6172 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_PACKET,
6173 + "Found type %x\n", type);
6175 + switch (type) {
6176 + case MPLS_INIT_MSGTYPE:
6178 + MPLS_MSGPTR(Init) = &msg->u.init;
6179 + encodedSize = Mpls_decodeLdpInitMsg(MPLS_MSGPARAM(Init),
6180 + b->current, max_mesg_size);
6181 + LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_INIT, MPLS_TRACE_STATE_RECV,
6182 + ldp_buf_dump(g->user_data, b, encodedSize));
6183 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
6184 + LDP_TRACE_FLAG_INIT, "decodedSize for Init msg = %d\n", encodedSize);
6185 + if (encodedSize < 0) {
6186 + goto ldp_decode_one_mesg;
6188 + LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
6189 + printHeader(g->user_data, &msg->header),
6190 + printInitMsg(g->user_data, MPLS_MSGPARAM(Init)));
6191 + b->current += encodedSize;
6192 + mesgSize += encodedSize;
6193 + break;
6195 + case MPLS_NOT_MSGTYPE:
6197 + MPLS_MSGPTR(Notif) = &msg->u.notif;
6198 + encodedSize = Mpls_decodeLdpNotMsg(MPLS_MSGPARAM(Notif),
6199 + b->current, max_mesg_size);
6200 + LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_NOTIF, MPLS_TRACE_STATE_RECV,
6201 + ldp_buf_dump(g->user_data, b,
6202 + (encodedSize < 0) ? max_mesg_size : encodedSize));
6203 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_NOTIF,
6204 + "decodedSize for Notif msg = %d\n", encodedSize);
6205 + if (encodedSize < 0) {
6206 + goto ldp_decode_one_mesg;
6208 + LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
6209 + LDP_TRACE_FLAG_NOTIF,
6210 + printHeader(g->user_data, &msg->header),
6211 + printNotMsg(g->user_data, MPLS_MSGPARAM(Notif)));
6212 + b->current += encodedSize;
6213 + mesgSize += encodedSize;
6214 + break;
6216 + case MPLS_KEEPAL_MSGTYPE:
6218 + MPLS_MSGPTR(KeepAl) = &msg->u.keep;
6219 + encodedSize = Mpls_decodeLdpKeepAliveMsg(MPLS_MSGPARAM(KeepAl),
6220 + b->current, max_mesg_size);
6221 + LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_PERIODIC,
6222 + MPLS_TRACE_STATE_RECV, ldp_buf_dump(g->user_data, b, encodedSize));
6223 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
6224 + LDP_TRACE_FLAG_PERIODIC,
6225 + "decodedSize for KeepAlive msg = %d\n", encodedSize);
6226 + if (encodedSize < 0) {
6227 + goto ldp_decode_one_mesg;
6229 + LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
6230 + LDP_TRACE_FLAG_PERIODIC,
6231 + printHeader(g->user_data, &msg->header),
6232 + printKeepAliveMsg(g->user_data, MPLS_MSGPARAM(KeepAl)));
6233 + b->current += encodedSize;
6234 + mesgSize += encodedSize;
6235 + break;
6237 + case MPLS_HELLO_MSGTYPE:
6239 + MPLS_MSGPTR(Hello) = &msg->u.hello;
6240 + encodedSize = Mpls_decodeLdpHelloMsg(MPLS_MSGPARAM(Hello),
6241 + b->current, max_mesg_size);
6242 + LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_PERIODIC,
6243 + MPLS_TRACE_STATE_RECV, ldp_buf_dump(g->user_data, b, encodedSize));
6244 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
6245 + LDP_TRACE_FLAG_PERIODIC, "decodedSize for Hello msg = %d\n",
6246 + encodedSize);
6247 + if (encodedSize < 0) {
6248 + goto ldp_decode_one_mesg;
6250 + LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
6251 + LDP_TRACE_FLAG_PERIODIC,
6252 + printHeader(g->user_data, &msg->header),
6253 + printHelloMsg(g->user_data, MPLS_MSGPARAM(Hello)));
6254 + b->current += encodedSize;
6255 + mesgSize += encodedSize;
6256 + break;
6258 + case MPLS_LBLREQ_MSGTYPE:
6260 + MPLS_MSGPTR(LblReq) = &msg->u.request;
6261 + encodedSize = Mpls_decodeLdpLblReqMsg(MPLS_MSGPARAM(LblReq),
6262 + b->current, max_mesg_size);
6263 + LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_LABEL, MPLS_TRACE_STATE_RECV,
6264 + ldp_buf_dump(g->user_data, b, encodedSize));
6265 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
6266 + LDP_TRACE_FLAG_LABEL, "decodedSize for Req msg = %d\n", encodedSize);
6267 + if (encodedSize < 0) {
6268 + goto ldp_decode_one_mesg;
6270 + LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
6271 + LDP_TRACE_FLAG_LABEL,
6272 + printHeader(g->user_data, &msg->header),
6273 + printLlbReqMsg(g->user_data, MPLS_MSGPARAM(LblReq)));
6274 + b->current += encodedSize;
6275 + mesgSize += encodedSize;
6276 + break;
6278 + case MPLS_LBLMAP_MSGTYPE:
6280 + MPLS_MSGPTR(LblMap) = &msg->u.map;
6281 + encodedSize = Mpls_decodeLdpLblMapMsg(MPLS_MSGPARAM(LblMap),
6282 + b->current, max_mesg_size);
6283 + LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_LABEL, MPLS_TRACE_STATE_RECV,
6284 + ldp_buf_dump(g->user_data, b, encodedSize));
6285 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
6286 + LDP_TRACE_FLAG_LABEL, "decodedSize for Map msg = %d\n", encodedSize);
6287 + if (encodedSize < 0) {
6288 + goto ldp_decode_one_mesg;
6290 + LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
6291 + LDP_TRACE_FLAG_LABEL,
6292 + printHeader(g->user_data, &msg->header),
6293 + printLlbMapMsg(g->user_data, MPLS_MSGPARAM(LblMap)));
6294 + b->current += encodedSize;
6295 + mesgSize += encodedSize;
6296 + break;
6298 + case MPLS_ADDR_MSGTYPE:
6299 + case MPLS_ADDRWITH_MSGTYPE:
6301 + MPLS_MSGPTR(Adr) = &msg->u.addr;
6302 + encodedSize = Mpls_decodeLdpAdrMsg(MPLS_MSGPARAM(Adr),
6303 + b->current, max_mesg_size);
6304 + LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_ADDRESS,
6305 + MPLS_TRACE_STATE_RECV, ldp_buf_dump(g->user_data, b, encodedSize));
6306 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
6307 + LDP_TRACE_FLAG_ADDRESS, "decodedSize for Adr msg = %d\n",
6308 + encodedSize);
6309 + if (encodedSize < 0) {
6310 + goto ldp_decode_one_mesg;
6312 + LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
6313 + LDP_TRACE_FLAG_ADDRESS,
6314 + printHeader(g->user_data, &msg->header),
6315 + printAddressMsg(g->user_data, MPLS_MSGPARAM(Adr)));
6316 + b->current += encodedSize;
6317 + mesgSize += encodedSize;
6318 + break;
6320 + case MPLS_LBLWITH_MSGTYPE:
6321 + case MPLS_LBLREL_MSGTYPE:
6323 + MPLS_MSGPTR(Lbl_W_R_) = &msg->u.release;
6324 + encodedSize = Mpls_decodeLdpLbl_W_R_Msg(MPLS_MSGPARAM(Lbl_W_R_),
6325 + b->current, max_mesg_size);
6326 + LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_LABEL, MPLS_TRACE_STATE_RECV,
6327 + ldp_buf_dump(g->user_data, b, encodedSize));
6328 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
6329 + LDP_TRACE_FLAG_LABEL,
6330 + "decodedSize for Lbl Release/Mapping msg = %d\n", encodedSize);
6331 + if (encodedSize < 0) {
6332 + goto ldp_decode_one_mesg;
6334 + LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
6335 + LDP_TRACE_FLAG_LABEL,
6336 + printHeader(g->user_data, &msg->header),
6337 + printLbl_W_R_Msg(g->user_data, MPLS_MSGPARAM(Lbl_W_R_)));
6338 + b->current += encodedSize;
6339 + mesgSize += encodedSize;
6340 + break;
6342 + case MPLS_LBLABORT_MSGTYPE:
6344 + MPLS_MSGPTR(LblAbort) = &msg->u.abort;
6345 + encodedSize = Mpls_decodeLdpLblAbortMsg(MPLS_MSGPARAM(LblAbort),
6346 + b->current, max_mesg_size);
6347 + LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_LABEL, MPLS_TRACE_STATE_RECV,
6348 + ldp_buf_dump(g->user_data, b, encodedSize));
6349 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
6350 + LDP_TRACE_FLAG_LABEL, "decodedSize for Abort msg = %d\n",
6351 + encodedSize);
6352 + if (encodedSize < 0) {
6353 + goto ldp_decode_one_mesg;
6355 + LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
6356 + LDP_TRACE_FLAG_LABEL,
6357 + printHeader(g->user_data, &msg->header),
6358 + printLlbAbortMsg(g->user_data, MPLS_MSGPARAM(LblAbort)));
6359 + b->current += encodedSize;
6360 + mesgSize += encodedSize;
6361 + break;
6363 + default:
6365 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
6366 + LDP_TRACE_FLAG_PACKET, "Unknown message type = %x\n", type);
6367 + goto ldp_decode_one_mesg;
6369 + } /* switch */
6371 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
6372 + LDP_TRACE_FLAG_PACKET, "Mesg size: %d (%d)\n", mesgSize, b->size);
6374 + b->current_size -= mesgSize;
6376 + LDP_EXIT(g->user_data, "ldp_decode_one_mesg");
6377 + return MPLS_SUCCESS;
6379 +ldp_decode_one_mesg:
6381 + LDP_EXIT(g->user_data, "ldp_decode_one_mesg - failure");
6382 + return MPLS_FAILURE;
6384 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_buf.h quagga-mpls/ldpd/ldp_buf.h
6385 --- quagga/ldpd/ldp_buf.h 1969-12-31 18:00:00.000000000 -0600
6386 +++ quagga-mpls/ldpd/ldp_buf.h 2006-08-09 21:56:14.000000000 -0500
6387 @@ -0,0 +1,32 @@
6390 + * Copyright (C) James R. Leu 2000
6391 + * jleu@mindspring.com
6393 + * This software is covered under the LGPL, for more
6394 + * info check out http://www.gnu.org/copyleft/lgpl.html
6395 + */
6397 +#ifndef _LDP_BUF_H_
6398 +#define _LDP_BUF_H_
6400 +#include "mpls_mm_impl.h"
6402 +#define MPLS_MSGMALLOC( e ) mplsLdp ## e ## Msg_t *test ## e ## Msg = (mplsLdp ## e ## Msg_t*)ldp_malloc(sizeof(mplsLdp ## e ## Msg_t))
6403 +#define MPLS_MSGSTRUCT( e ) mplsLdp ## e ## Msg_t test ## e ## Msg
6404 +#define MPLS_MSGPTR( e ) mplsLdp ## e ## Msg_t *test ## e ## Msg
6405 +#define MPLS_MSGCAST( e , f ) test ## e ## Msg = (mplsLdp ## e ## Msg_t*) f
6406 +#define MPLS_MSGPARAM( e ) test ## e ## Msg
6408 +#include "ldp_struct.h"
6410 +extern ldp_buf *ldp_buf_create(int);
6411 +extern void ldp_buf_delete(ldp_buf *);
6412 +extern int ldp_encode_one_mesg(ldp_global * g, uint32_t lsraddr,
6413 + int label_space, ldp_buf * b, ldp_mesg * msg);
6414 +extern int ldp_decode_one_mesg(ldp_global * g, ldp_buf * pdu, ldp_mesg * msg);
6415 +extern mpls_return_enum ldp_decode_header(ldp_global * g, ldp_buf * b,
6417 + ldp_mesg * msg);
6419 +#endif
6420 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp.c quagga-mpls/ldpd/ldp.c
6421 --- quagga/ldpd/ldp.c 1969-12-31 18:00:00.000000000 -0600
6422 +++ quagga-mpls/ldpd/ldp.c 2006-11-21 20:13:36.000000000 -0600
6423 @@ -0,0 +1,195 @@
6424 +#include <zebra.h>
6426 +#include "memory.h"
6427 +#include "log.h"
6428 +#include "thread.h"
6429 +#include "prefix.h"
6430 +#include "table.h"
6431 +#include "linklist.h"
6432 +#include "filter.h"
6433 +#include "vty.h"
6434 +#include "plist.h"
6436 +#include "ldp.h"
6437 +#include "ldp_cfg.h"
6438 +#include "ldp_struct.h"
6439 +#include "ldp_interface.h"
6440 +#include "ldp_zebra.h"
6442 +#include "impl_fib.h"
6444 +int ldp_shutdown(struct ldp *ldp) {
6445 + ldp_global g;
6447 + g.admin_state = MPLS_ADMIN_DISABLE;
6448 + return ldp_cfg_global_set(ldp->h,&g,LDP_GLOBAL_CFG_ADMIN_STATE);
6451 +int ldp_startup(struct ldp *ldp) {
6452 + ldp_global g;
6454 + g.admin_state = MPLS_ADMIN_ENABLE;
6455 + return ldp_cfg_global_set(ldp->h,&g,LDP_GLOBAL_CFG_ADMIN_STATE);
6458 +int ldp_admin_state_start(struct ldp *ldp) {
6459 + if (ldp->admin_up == MPLS_BOOL_TRUE) {
6460 + return ldp_shutdown(ldp);
6462 + return MPLS_SUCCESS;
6465 +int ldp_admin_state_finish(struct ldp *ldp) {
6466 + if (ldp->admin_up == MPLS_BOOL_TRUE) {
6467 + return ldp_startup(ldp);
6469 + return MPLS_SUCCESS;
6472 +int do_ldp_router_id_update(struct ldp *ldp, unsigned int router_id) {
6473 + ldp_global g;
6474 + g.lsr_identifier.type = MPLS_FAMILY_IPV4;
6475 + g.lsr_identifier.u.ipv4 = router_id;
6476 + g.transport_address.type = MPLS_FAMILY_NONE;
6477 + g.transport_address.u.ipv4 = 0;
6479 + if (ldp->trans_addr == LDP_TRANS_ADDR_LSRID) {
6480 + g.transport_address.type = MPLS_FAMILY_IPV4;
6481 + g.transport_address.u.ipv4 = router_id;
6484 + return ldp_cfg_global_set(ldp->h,&g,
6485 + LDP_GLOBAL_CFG_LSR_IDENTIFIER|LDP_GLOBAL_CFG_TRANS_ADDR);
6488 +int ldp_router_id_update(struct ldp *ldp, struct prefix *router_id) {
6490 + zlog_info("router-id update %s", inet_ntoa(router_id->u.prefix4));
6492 + if (!ldp->lsr_id_is_static) {
6493 + ldp_admin_state_start(ldp);
6495 + do_ldp_router_id_update(ldp, ntohl(router_id->u.prefix4.s_addr));
6497 + ldp_admin_state_finish(ldp);
6499 + return 0;
6502 +/* LDP instance top. */
6503 +struct ldp *ldp_top = NULL;
6505 +struct ldp *ldp_new(void) {
6506 + struct ldp *new = XMALLOC(MTYPE_LDP, sizeof(struct ldp));
6507 + ldp_global g;
6508 + struct route_node *rn;
6509 + struct prefix n;
6511 + struct interface *ifp;
6512 + struct connected *c;
6513 + struct listnode *node, *cnode;
6514 + struct ldp_interface *li;
6515 + struct ldp_addr addr;
6516 + struct prefix *p;
6518 + memset(new,0,sizeof(*new));
6520 + new->h = ldp_cfg_open(new);
6521 + new->admin_up = MPLS_BOOL_TRUE;
6522 + new->lsr_id_is_static = 0;
6524 + new->egress = LDP_EGRESS_CONNECTED;
6525 + new->address = LDP_ADDRESS_ALL;
6526 + new->peer_list = list_new();
6528 + ldp_top = new;
6530 + do_ldp_router_id_update(new, ntohl(router_id.u.prefix4.s_addr));
6531 + g.admin_state = MPLS_ADMIN_ENABLE;
6533 + ldp_cfg_global_set(new->h,&g, LDP_GLOBAL_CFG_LSR_HANDLE|
6534 + LDP_GLOBAL_CFG_ADMIN_STATE);
6536 + n.u.prefix4.s_addr = htonl(INADDR_LOOPBACK);
6537 + n.prefixlen = 8;
6538 + n.family = AF_INET;
6540 + for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
6541 + MPLS_ASSERT(ifp->info);
6542 + li = ifp->info;
6544 + ldp_interface_create(li);
6546 + for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
6547 + p = c->address;
6548 + if (p->family == AF_INET) {
6549 + if (!prefix_match(&n, c->address)) {
6550 + prefix2mpls_inet_addr(p, &addr.address);
6551 + ldp_cfg_if_addr_set(new->h, &li->iff, &addr, LDP_CFG_ADD);
6556 + if (li->configured == MPLS_BOOL_TRUE)
6557 + ldp_interface_create2(li);
6560 + ldp_zebra_startup();
6562 + return new;
6565 +struct ldp *ldp_get() {
6566 + if (ldp_top) {
6567 + return ldp_top;
6569 + return NULL;
6572 +void ldp_finish(struct ldp *ldp) {
6573 + struct ldp_interface *li;
6574 + struct interface *ifp;
6575 + struct listnode* node;
6576 + int flag;
6578 + ldp_zebra_shutdown();
6580 + ldp_admin_state_start(ldp);
6582 + for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
6583 + MPLS_ASSERT(ifp->info);
6584 + flag = li->iff.index ? 1 : 0;
6585 + li = ifp->info;
6586 + ldp_interface_delete(li);
6587 + if (flag) {
6588 + li->configured = MPLS_BOOL_TRUE;
6589 + li->admin_up = MPLS_BOOL_TRUE;
6593 + ldp_cfg_close(ldp->h);
6594 + list_free(ldp->peer_list);
6596 + XFREE(MTYPE_LDP,ldp);
6597 + ldp_top = NULL;
6600 +#if 0
6601 +/* Update access-list list. */
6602 +void mpls_access_list_update(struct access_list *access) {
6605 +/* Update prefix-list list. */
6606 +void mpls_prefix_list_update(struct prefix_list *plist) {
6608 +#endif
6610 +void ldp_init() {
6612 +#if 0
6613 + access_list_init();
6614 + access_list_add_hook(mpls_access_list_update);
6615 + access_list_delete_hook(mpls_access_list_update);
6616 +#endif
6619 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_cfg.c quagga-mpls/ldpd/ldp_cfg.c
6620 --- quagga/ldpd/ldp_cfg.c 1969-12-31 18:00:00.000000000 -0600
6621 +++ quagga-mpls/ldpd/ldp_cfg.c 2008-02-28 22:25:08.000000000 -0600
6622 @@ -0,0 +1,2929 @@
6625 + * Copyright (C) James R. Leu 2000
6626 + * jleu@mindspring.com
6628 + * This software is covered under the LGPL, for more
6629 + * info check out http://www.gnu.org/copyleft/lgpl.html
6630 + */
6632 +#include "ldp_struct.h"
6633 +#include "ldp_cfg.h"
6634 +#include "ldp_global.h"
6635 +#include "ldp_entity.h"
6636 +#include "ldp_attr.h"
6637 +#include "ldp_if.h"
6638 +#include "ldp_peer.h"
6639 +#include "ldp_fec.h"
6640 +#include "ldp_addr.h"
6641 +#include "ldp_nexthop.h"
6642 +#include "ldp_tunnel.h"
6643 +#include "ldp_resource.h"
6644 +#include "mpls_ifmgr_impl.h"
6645 +#include "ldp_label_mapping.h"
6646 +#include "ldp_hop.h"
6647 +#include "ldp_hop_list.h"
6648 +#include "mpls_lock_impl.h"
6649 +#include "mpls_trace_impl.h"
6650 +#include "mpls_tree_impl.h"
6652 +mpls_cfg_handle ldp_cfg_open(mpls_instance_handle data)
6654 + ldp_global *g = ldp_global_create(data);
6656 + LDP_ENTER(data, "ldp_cfg_open");
6657 + LDP_EXIT(data, "ldp_cfg_open");
6659 + return (mpls_cfg_handle) g;
6662 +void ldp_cfg_close(mpls_cfg_handle g)
6664 + LDP_ENTER((mpls_instance_handle) g->user_data, "ldp_cfg_close");
6665 + ldp_global_delete(g);
6666 + LDP_EXIT((mpls_instance_handle) g->user_data, "ldp_cfg_close");
6669 +/******************* GLOBAL **********************/
6671 +void ldp_cfg_global_attr(mpls_cfg_handle handle) {
6672 + ldp_global *global = (ldp_global *) handle;
6673 + ldp_attr *attr = MPLS_LIST_HEAD(&global->attr);
6674 + while (attr) {
6675 + if (attr->state == LDP_LSP_STATE_MAP_SENT && attr->ds_attr) {
6676 + LDP_PRINT(global->user_data, "%p(%s) xc to %p(%s)", attr,
6677 + attr->session->session_name, attr->ds_attr,
6678 + attr->ds_attr->session->session_name);
6680 + attr = MPLS_LIST_NEXT(&global->attr, attr, _global);
6684 +mpls_return_enum ldp_cfg_global_get(mpls_cfg_handle handle, ldp_global * g,
6685 + uint32_t flag)
6687 + ldp_global *global = (ldp_global *) handle;
6689 + MPLS_ASSERT(global !=NULL);
6691 + LDP_ENTER(global->user_data, "ldp_cfg_global_get");
6693 + mpls_lock_get(global->global_lock); /* LOCK */
6695 + if (flag & LDP_GLOBAL_CFG_LSR_IDENTIFIER) {
6696 + memcpy(&(g->lsr_identifier), &(global->lsr_identifier),
6697 + sizeof(mpls_inet_addr));
6699 + if (flag & LDP_GLOBAL_CFG_ADMIN_STATE) {
6700 + g->admin_state = global->admin_state;
6702 + if (flag & LDP_GLOBAL_CFG_CONTROL_MODE) {
6703 + g->lsp_control_mode = global->lsp_control_mode;
6705 + if (flag & LDP_GLOBAL_CFG_RETENTION_MODE) {
6706 + g->label_retention_mode = global->label_retention_mode;
6708 + if (flag & LDP_GLOBAL_CFG_REPAIR_MODE) {
6709 + g->lsp_repair_mode = global->lsp_repair_mode;
6711 + if (flag & LDP_GLOBAL_CFG_PROPOGATE_RELEASE) {
6712 + g->propagate_release = global->propagate_release;
6714 + if (flag & LDP_GLOBAL_CFG_LABEL_MERGE) {
6715 + g->label_merge = global->label_merge;
6717 + if (flag & LDP_GLOBAL_CFG_LOOP_DETECTION_MODE) {
6718 + g->loop_detection_mode = global->loop_detection_mode;
6720 + if (flag & LDP_GLOBAL_CFG_TTLLESS_DOMAIN) {
6721 + g->ttl_less_domain = global->ttl_less_domain;
6723 + if (flag & LDP_GLOBAL_CFG_LOCAL_TCP_PORT) {
6724 + g->local_tcp_port = global->local_tcp_port;
6726 + if (flag & LDP_GLOBAL_CFG_LOCAL_UDP_PORT) {
6727 + g->local_udp_port = global->local_udp_port;
6729 + if (flag & LDP_GLOBAL_CFG_TRANS_ADDR) {
6730 + memcpy(&(g->transport_address), &(global->transport_address),
6731 + sizeof(mpls_inet_addr));
6733 + if (flag & LDP_GLOBAL_CFG_KEEPALIVE_TIMER) {
6734 + g->keepalive_timer = global->keepalive_timer;
6736 + if (flag & LDP_GLOBAL_CFG_KEEPALIVE_INTERVAL) {
6737 + g->keepalive_interval = global->keepalive_interval;
6739 + if (flag & LDP_GLOBAL_CFG_HELLOTIME_TIMER) {
6740 + g->hellotime_timer = global->hellotime_timer;
6742 + if (flag & LDP_GLOBAL_CFG_HELLOTIME_INTERVAL) {
6743 + g->hellotime_interval = global->hellotime_interval;
6745 +#if MPLS_USE_LSR
6746 + if (flag & LDP_GLOBAL_CFG_LSR_HANDLE) {
6747 + g->lsr_handle = global->lsr_handle;
6749 +#endif
6751 + mpls_lock_release(global->global_lock); /* UNLOCK */
6753 + LDP_EXIT(global->user_data, "ldp_cfg_global_get");
6755 + return MPLS_SUCCESS;
6758 +mpls_return_enum ldp_cfg_global_test(mpls_cfg_handle handle, ldp_global * g,
6759 + uint32_t flag)
6761 + ldp_global *global = (ldp_global *) handle;
6762 + mpls_return_enum retval = MPLS_SUCCESS;
6764 + MPLS_ASSERT(global !=NULL);
6766 + LDP_ENTER(global->user_data, "ldp_cfg_global_test");
6768 + mpls_lock_get(global->global_lock); /* LOCK */
6770 + if (global->admin_state == MPLS_ADMIN_ENABLE && (flag & LDP_GLOBAL_CFG_WHEN_DOWN))
6771 + retval = MPLS_FAILURE;
6773 + mpls_lock_release(global->global_lock); /* UNLOCK */
6775 + LDP_EXIT(global->user_data, "ldp_cfg_global_test");
6777 + return retval;
6780 +mpls_return_enum ldp_cfg_global_set(mpls_cfg_handle handle, ldp_global * g,
6781 + uint32_t flag)
6783 + ldp_global *global = (ldp_global *) handle;
6784 + mpls_return_enum retval = MPLS_FAILURE;
6786 + MPLS_ASSERT(global !=NULL);
6788 + LDP_ENTER(global->user_data, "ldp_cfg_global_set");
6790 + mpls_lock_get(global->global_lock); /* LOCK */
6792 + if ((global->admin_state == MPLS_ADMIN_ENABLE && (flag & LDP_GLOBAL_CFG_WHEN_DOWN)))
6793 + goto ldp_cfg_global_set_end;
6795 + if (flag & LDP_GLOBAL_CFG_CONTROL_MODE) {
6796 + global->lsp_control_mode = g->lsp_control_mode;
6798 + if (flag & LDP_GLOBAL_CFG_RETENTION_MODE) {
6799 + global->label_retention_mode = g->label_retention_mode;
6801 + if (flag & LDP_GLOBAL_CFG_REPAIR_MODE) {
6802 + global->lsp_repair_mode = g->lsp_repair_mode;
6804 + if (flag & LDP_GLOBAL_CFG_PROPOGATE_RELEASE) {
6805 + global->propagate_release = g->propagate_release;
6807 + if (flag & LDP_GLOBAL_CFG_LABEL_MERGE) {
6808 + global->label_merge = g->label_merge;
6810 + if (flag & LDP_GLOBAL_CFG_LOOP_DETECTION_MODE) {
6811 + global->loop_detection_mode = g->loop_detection_mode;
6813 + if (flag & LDP_GLOBAL_CFG_TTLLESS_DOMAIN) {
6814 + global->ttl_less_domain = g->ttl_less_domain;
6816 + if (flag & LDP_GLOBAL_CFG_LOCAL_TCP_PORT) {
6817 + global->local_tcp_port = g->local_tcp_port;
6819 + if (flag & LDP_GLOBAL_CFG_LOCAL_UDP_PORT) {
6820 + global->local_udp_port = g->local_udp_port;
6822 + if (flag & LDP_GLOBAL_CFG_LSR_IDENTIFIER) {
6823 + memcpy(&(global->lsr_identifier), &(g->lsr_identifier),
6824 + sizeof(mpls_inet_addr));
6826 +#if MPLS_USE_LSR
6827 + if (flag & LDP_GLOBAL_CFG_LSR_HANDLE) {
6828 + global->lsr_handle = g->lsr_handle;
6830 +#endif
6831 + if (flag & LDP_GLOBAL_CFG_ADMIN_STATE) {
6832 + if (global->admin_state == MPLS_ADMIN_ENABLE && g->admin_state == MPLS_ADMIN_DISABLE) {
6833 + ldp_global_shutdown(global);
6834 + } else if (global->admin_state == MPLS_ADMIN_DISABLE && g->admin_state ==
6835 + MPLS_ADMIN_ENABLE) {
6836 + ldp_global_startup(global);
6839 + if (flag & LDP_GLOBAL_CFG_TRANS_ADDR) {
6840 + memcpy(&(global->transport_address), &(g->transport_address),
6841 + sizeof(mpls_inet_addr));
6843 + if (flag & LDP_GLOBAL_CFG_KEEPALIVE_TIMER) {
6844 + if (g->keepalive_timer == 0) {
6845 + global->keepalive_timer = LDP_ENTITY_DEF_KEEPALIVE_TIMER;
6846 + } else {
6847 + global->keepalive_timer = g->keepalive_timer;
6850 + if (flag & LDP_GLOBAL_CFG_KEEPALIVE_INTERVAL) {
6851 + if (g->keepalive_interval == 0) {
6852 + global->keepalive_interval = LDP_ENTITY_DEF_KEEPALIVE_INTERVAL;
6853 + } else {
6854 + global->keepalive_interval = g->keepalive_interval;
6857 + if (flag & LDP_GLOBAL_CFG_HELLOTIME_TIMER) {
6858 + if (g->hellotime_timer == 0) {
6859 + global->hellotime_timer = LDP_ENTITY_DEF_HELLOTIME_TIMER;
6860 + } else {
6861 + global->hellotime_timer = g->hellotime_timer;
6864 + if (flag & LDP_GLOBAL_CFG_HELLOTIME_INTERVAL) {
6865 + if (g->hellotime_interval == 0) {
6866 + global->hellotime_interval = LDP_ENTITY_DEF_HELLOTIME_INTERVAL;
6867 + } else {
6868 + global->hellotime_interval = g->hellotime_interval;
6871 +#if MPLS_USE_LSR
6872 + if (flag & LDP_GLOBAL_CFG_LSR_HANDLE) {
6873 + global->lsr_handle = g->lsr_handle ;
6875 +#endif
6876 + global->configuration_sequence_number++;
6878 + retval = MPLS_SUCCESS;
6880 +ldp_cfg_global_set_end:
6882 + mpls_lock_release(global->global_lock); /* UNLOCK */
6884 + LDP_EXIT(global->user_data, "ldp_cfg_global_set");
6886 + return retval;
6889 +/******************* ENTITY **********************/
6891 +/* must set ldp_entity->index */
6892 +mpls_return_enum ldp_cfg_entity_get(mpls_cfg_handle handle, ldp_entity * e,
6893 + uint32_t flag)
6895 + ldp_global *global = (ldp_global *) handle;
6896 + ldp_entity *entity = NULL;
6897 + mpls_return_enum retval = MPLS_FAILURE;
6899 + MPLS_ASSERT(global !=NULL && e != NULL);
6901 + LDP_ENTER(global->user_data, "ldp_cfg_entity_get");
6903 + mpls_lock_get(global->global_lock); /* LOCK */
6905 + if (ldp_global_find_entity_index(global, e->index, &entity) != MPLS_SUCCESS)
6906 + goto ldp_cfg_entity_get_end;
6908 + if (flag & LDP_ENTITY_CFG_ADMIN_STATE) {
6909 + e->admin_state = entity->admin_state;
6911 + if (flag & LDP_ENTITY_CFG_TRANS_ADDR) {
6912 + e->transport_address = entity->transport_address;
6914 + if (flag & LDP_ENTITY_CFG_PROTO_VER) {
6915 + e->protocol_version = entity->protocol_version;
6917 + if (flag & LDP_ENTITY_CFG_REMOTE_TCP) {
6918 + e->remote_tcp_port = entity->remote_tcp_port;
6920 + if (flag & LDP_ENTITY_CFG_REMOTE_UDP) {
6921 + e->remote_udp_port = entity->remote_udp_port;
6923 + if (flag & LDP_ENTITY_CFG_MAX_PDU) {
6924 + e->max_pdu = entity->max_pdu;
6926 + if (flag & LDP_ENTITY_CFG_KEEPALIVE_TIMER) {
6927 + e->keepalive_timer = entity->keepalive_timer;
6929 + if (flag & LDP_ENTITY_CFG_KEEPALIVE_INTERVAL) {
6930 + e->keepalive_interval = entity->keepalive_interval;
6932 + if (flag & LDP_ENTITY_CFG_HELLOTIME_TIMER) {
6933 + e->hellotime_timer = entity->hellotime_timer;
6935 + if (flag & LDP_ENTITY_CFG_HELLOTIME_INTERVAL) {
6936 + e->hellotime_interval = entity->hellotime_interval;
6938 + if (flag & LDP_ENTITY_CFG_SESSION_SETUP_COUNT) {
6939 + e->session_setup_count = entity->session_setup_count;
6941 + if (flag & LDP_ENTITY_CFG_SESSION_BACKOFF_TIMER) {
6942 + e->session_backoff_timer = entity->session_backoff_timer;
6944 + if (flag & LDP_ENTITY_CFG_DISTRIBUTION_MODE) {
6945 + e->label_distribution_mode = entity->label_distribution_mode;
6947 + if (flag & LDP_ENTITY_CFG_PATHVECTOR_LIMIT) {
6948 + e->path_vector_limit = entity->path_vector_limit;
6950 + if (flag & LDP_ENTITY_CFG_HOPCOUNT_LIMIT) {
6951 + e->hop_count_limit = entity->hop_count_limit;
6953 + if (flag & LDP_ENTITY_CFG_REQUEST_COUNT) {
6954 + e->label_request_count = entity->label_request_count;
6956 + if (flag & LDP_ENTITY_CFG_REQUEST_TIMER) {
6957 + e->label_request_timer = entity->label_request_timer;
6959 + if (flag & LDP_ENTITY_CFG_TYPE) {
6960 + e->entity_type = entity->entity_type;
6962 + if (flag & LDP_ENTITY_CFG_SUB_INDEX) {
6963 + e->sub_index = entity->sub_index;
6965 + if (flag & LDP_ENTITY_CFG_MESG_TX) {
6966 + e->mesg_tx = entity->mesg_tx;
6968 + if (flag & LDP_ENTITY_CFG_MESG_RX) {
6969 + e->mesg_rx = entity->mesg_rx;
6971 + if (flag & LDP_ENTITY_CFG_ADJ_COUNT) {
6972 + e->adj_count = entity->adj_root.count;
6974 + if (flag & LDP_ENTITY_CFG_ADJ_INDEX) {
6975 + ldp_adj *a = MPLS_LIST_HEAD(&entity->adj_root);
6976 + e->adj_index = a ? a->index : 0;
6978 + if (flag & LDP_ENTITY_CFG_INHERIT_FLAG) {
6979 + e->inherit_flag = entity->inherit_flag;
6981 + retval = MPLS_SUCCESS;
6983 +ldp_cfg_entity_get_end:
6985 + mpls_lock_release(global->global_lock); /* UNLOCK */
6987 + LDP_EXIT(global->user_data, "ldp_cfg_entity_get");
6989 + return retval;
6992 +mpls_return_enum ldp_cfg_entity_getnext(mpls_cfg_handle handle, ldp_entity * e,
6993 + uint32_t flag)
6995 + ldp_global *g = (ldp_global *) handle;
6996 + ldp_entity *entity = NULL;
6997 + mpls_return_enum r = MPLS_FAILURE;
6998 + mpls_bool done = MPLS_BOOL_FALSE;
6999 + int index;
7001 + LDP_ENTER(g->user_data, "ldp_cfg_entity_getnext");
7003 + if (e->index == 0) {
7004 + index = 1;
7005 + } else {
7006 + index = e->index + 1;
7009 + mpls_lock_get(g->global_lock); /* LOCK */
7010 + while (done == MPLS_BOOL_FALSE) {
7011 + switch ((r = ldp_global_find_entity_index(g, index, &entity))) {
7012 + case MPLS_SUCCESS:
7013 + case MPLS_END_OF_LIST:
7014 + done = MPLS_BOOL_TRUE;
7015 + break;
7016 + case MPLS_FAILURE:
7017 + break;
7018 + default:
7019 + MPLS_ASSERT(0);
7021 + index++;
7023 + mpls_lock_release(g->global_lock); /* UNLOCK */
7025 + if (r == MPLS_SUCCESS) {
7026 + e->index = entity->index;
7027 + LDP_EXIT(g->user_data, "ldp_cfg_entity_getnext");
7028 + return ldp_cfg_entity_get(g, e, flag);
7030 + LDP_EXIT(g->user_data, "ldp_cfg_entity_getnext");
7031 + return r;
7034 +mpls_return_enum ldp_cfg_entity_test(mpls_cfg_handle handle, ldp_entity * e,
7035 + uint32_t flag)
7037 + ldp_global *global = (ldp_global *) handle;
7038 + ldp_entity *entity = NULL;
7039 + mpls_return_enum retval = MPLS_FAILURE;
7041 + MPLS_ASSERT(global !=NULL);
7043 + LDP_ENTER(global->user_data, "ldp_cfg_entity_test");
7045 + mpls_lock_get(global->global_lock); /* LOCK */
7047 + if (!(flag & LDP_CFG_ADD)) {
7048 + if (e == NULL)
7049 + goto ldp_cfg_entity_test_end;
7051 + ldp_global_find_entity_index(global, e->index, &entity);
7052 + } else {
7053 + retval = MPLS_SUCCESS;
7054 + goto ldp_cfg_entity_test_end;
7057 + if (entity == NULL) {
7058 + goto ldp_cfg_entity_test_end;
7061 + if ((ldp_entity_is_active(entity) == MPLS_BOOL_TRUE) &&
7062 + (flag & LDP_ENTITY_CFG_WHEN_DOWN)) {
7063 + goto ldp_cfg_entity_test_end;
7066 + retval = MPLS_SUCCESS;
7068 +ldp_cfg_entity_test_end:
7069 + mpls_lock_release(global->global_lock); /* UNLOCK */
7071 + LDP_EXIT(global->user_data, "ldp_cfg_entity_test");
7073 + return retval;
7076 +/* must set ldp_entity->index if not an add */
7077 +mpls_return_enum ldp_cfg_entity_set(mpls_cfg_handle handle, ldp_entity * e,
7078 + uint32_t flag)
7080 + ldp_global *global = (ldp_global *) handle;
7081 + ldp_entity *entity = NULL;
7082 + mpls_return_enum retval = MPLS_FAILURE;
7084 + MPLS_ASSERT(global !=NULL && e != NULL);
7086 + LDP_ENTER(global->user_data, "ldp_cfg_entity_set");
7088 + mpls_lock_get(global->global_lock); /* LOCK */
7090 + if (flag & LDP_CFG_ADD) {
7091 + entity = ldp_entity_create();
7092 + _ldp_global_add_entity(global, entity);
7094 + e->index = entity->index;
7095 + } else {
7096 + ldp_global_find_entity_index(global, e->index, &entity);
7099 + if (entity == NULL) {
7100 + LDP_PRINT(global->user_data, "ldp_cfg_entity_set: can't find entity\n");
7101 + goto ldp_cfg_entity_set_end;
7104 + if ((ldp_entity_is_active(entity) == MPLS_BOOL_TRUE) &&
7105 + (flag & LDP_ENTITY_CFG_WHEN_DOWN)) {
7106 + LDP_PRINT(global->user_data, "ldp_cfg_entity_set: entity is active\n");
7107 + goto ldp_cfg_entity_set_end;
7110 + if (flag & LDP_CFG_DEL) {
7111 + switch (entity->entity_type) {
7112 + case LDP_DIRECT:
7113 + ldp_entity_del_if(global, entity);
7114 + break;
7115 + case LDP_INDIRECT:
7116 + ldp_entity_del_peer(entity);
7117 + break;
7118 + default:
7119 + MPLS_ASSERT(0);
7121 + _ldp_global_del_entity(global, entity);
7123 + retval = MPLS_SUCCESS;
7124 + goto ldp_cfg_entity_set_end;
7127 + if (flag & LDP_ENTITY_CFG_SUB_INDEX) {
7128 + if (entity->sub_index != 0) {
7129 + /* unlink the old sub object */
7130 + switch (entity->entity_type) {
7131 + case LDP_DIRECT:
7132 + ldp_entity_del_if(global, entity);
7133 + break;
7134 + case LDP_INDIRECT:
7135 + ldp_entity_del_peer(entity);
7136 + break;
7137 + default:
7138 + MPLS_ASSERT(0);
7142 + /* link the new sub object */
7143 + switch (e->entity_type) {
7144 + case LDP_DIRECT:
7146 + ldp_if *iff = NULL;
7147 + if (ldp_global_find_if_index(global, e->sub_index,
7148 + &iff) != MPLS_SUCCESS) {
7149 + LDP_PRINT(global->user_data,
7150 + "ldp_cfg_entity_set: no such interface\n");
7152 + if (flag & LDP_CFG_ADD) {
7153 + _ldp_global_del_entity(global, entity);
7155 + goto ldp_cfg_entity_set_end;
7157 + ldp_entity_add_if(entity, iff);
7158 + break;
7160 + case LDP_INDIRECT:
7162 + ldp_peer *peer = NULL;
7164 + if (ldp_global_find_peer_index(global, e->sub_index, &peer) !=
7165 + MPLS_SUCCESS) {
7166 + LDP_PRINT(global->user_data, "ldp_cfg_entity_set: no such peer\n");
7168 + if (flag & LDP_CFG_ADD) {
7169 + _ldp_global_del_entity(global, entity);
7171 + goto ldp_cfg_entity_set_end;
7173 + ldp_entity_add_peer(entity, peer);
7174 + break;
7176 + default:
7177 + MPLS_ASSERT(0);
7181 + if (flag & LDP_ENTITY_CFG_TRANS_ADDR) {
7182 + if (e->transport_address.type == MPLS_FAMILY_NONE) {
7183 + entity->inherit_flag |= LDP_ENTITY_CFG_TRANS_ADDR;
7184 + } else {
7185 + entity->inherit_flag &= ~LDP_ENTITY_CFG_TRANS_ADDR;
7187 + memcpy(&entity->transport_address, &e->transport_address,
7188 + sizeof(mpls_inet_addr));;
7190 + if (flag & LDP_ENTITY_CFG_PROTO_VER) {
7191 + entity->protocol_version = e->protocol_version;
7193 + if (flag & LDP_ENTITY_CFG_REMOTE_TCP) {
7194 + entity->remote_tcp_port = e->remote_tcp_port;
7196 + if (flag & LDP_ENTITY_CFG_REMOTE_UDP) {
7197 + entity->remote_udp_port = e->remote_udp_port;
7199 + if (flag & LDP_ENTITY_CFG_MAX_PDU) {
7200 + entity->max_pdu = e->max_pdu;
7202 + if (flag & LDP_ENTITY_CFG_KEEPALIVE_TIMER) {
7203 + if (e->transport_address.type == MPLS_FAMILY_NONE) {
7204 + entity->inherit_flag |= LDP_ENTITY_CFG_KEEPALIVE_TIMER;
7205 + } else {
7206 + entity->inherit_flag &= ~LDP_ENTITY_CFG_KEEPALIVE_TIMER;
7208 + entity->keepalive_timer = e->keepalive_timer;
7210 + if (flag & LDP_ENTITY_CFG_KEEPALIVE_INTERVAL) {
7211 + if (e->transport_address.type == MPLS_FAMILY_NONE) {
7212 + entity->inherit_flag |= LDP_ENTITY_CFG_KEEPALIVE_INTERVAL;
7213 + } else {
7214 + entity->inherit_flag &= ~LDP_ENTITY_CFG_KEEPALIVE_INTERVAL;
7216 + entity->keepalive_interval = e->keepalive_interval;
7218 + if (flag & LDP_ENTITY_CFG_HELLOTIME_TIMER) {
7219 + if (e->transport_address.type == MPLS_FAMILY_NONE) {
7220 + entity->inherit_flag |= LDP_ENTITY_CFG_HELLOTIME_TIMER;
7221 + } else {
7222 + entity->inherit_flag &= ~LDP_ENTITY_CFG_HELLOTIME_TIMER;
7224 + entity->hellotime_timer = e->hellotime_timer;
7226 + if (flag & LDP_ENTITY_CFG_HELLOTIME_INTERVAL) {
7227 + if (e->transport_address.type == MPLS_FAMILY_NONE) {
7228 + entity->inherit_flag |= LDP_ENTITY_CFG_HELLOTIME_INTERVAL;
7229 + } else {
7230 + entity->inherit_flag &= ~LDP_ENTITY_CFG_HELLOTIME_INTERVAL;
7232 + entity->hellotime_interval = e->hellotime_interval;
7234 + if (flag & LDP_ENTITY_CFG_SESSION_SETUP_COUNT) {
7235 + entity->session_setup_count = e->session_setup_count;
7237 + if (flag & LDP_ENTITY_CFG_SESSION_BACKOFF_TIMER) {
7238 + entity->session_backoff_timer = e->session_backoff_timer;
7240 + if (flag & LDP_ENTITY_CFG_DISTRIBUTION_MODE) {
7241 + entity->label_distribution_mode = e->label_distribution_mode;
7243 + if (flag & LDP_ENTITY_CFG_PATHVECTOR_LIMIT) {
7244 + entity->path_vector_limit = e->path_vector_limit;
7246 + if (flag & LDP_ENTITY_CFG_HOPCOUNT_LIMIT) {
7247 + entity->hop_count_limit = e->hop_count_limit;
7249 + if (flag & LDP_ENTITY_CFG_REQUEST_COUNT) {
7250 + entity->label_request_count = e->label_request_count;
7252 + if (flag & LDP_ENTITY_CFG_REQUEST_TIMER) {
7253 + entity->label_request_timer = e->label_request_timer;
7255 + if (flag & LDP_ENTITY_CFG_TYPE) {
7256 + entity->entity_type = e->entity_type;
7258 + if (flag & LDP_ENTITY_CFG_ADMIN_STATE) {
7259 + if (ldp_entity_is_active(entity) == MPLS_BOOL_TRUE &&
7260 + e->admin_state == MPLS_ADMIN_DISABLE) {
7261 + if (ldp_entity_shutdown(global, entity, 0) == MPLS_FAILURE) {
7262 + goto ldp_cfg_entity_set_end;
7264 + } else if (ldp_entity_is_active(entity) == MPLS_BOOL_FALSE &&
7265 + e->admin_state == MPLS_ADMIN_ENABLE && ldp_entity_is_ready(entity) == MPLS_BOOL_TRUE) {
7266 + if (ldp_entity_startup(global, entity) == MPLS_FAILURE) {
7267 + goto ldp_cfg_entity_set_end;
7269 + } else {
7270 + LDP_PRINT(global->user_data, "ldp_cfg_entity_set: entity not ready\n");
7272 + goto ldp_cfg_entity_set_end;
7275 + if (flag & LDP_ENTITY_CFG_INHERIT_FLAG) {
7276 + entity->inherit_flag = e->inherit_flag;
7278 + global->configuration_sequence_number++;
7280 + retval = MPLS_SUCCESS;
7282 +ldp_cfg_entity_set_end:
7283 + mpls_lock_release(global->global_lock); /* UNLOCK */
7285 + LDP_EXIT(global->user_data, "ldp_cfg_entity_set");
7287 + return retval;
7290 +mpls_return_enum ldp_cfg_entity_adj_getnext(mpls_cfg_handle handle,
7291 + ldp_entity * e)
7293 + ldp_global *g = (ldp_global *) handle;
7294 + mpls_bool this_one = MPLS_BOOL_FALSE;
7295 + mpls_return_enum r = MPLS_FAILURE;
7296 + ldp_adj *adj_next = NULL;
7297 + ldp_adj *adj = NULL;
7298 + ldp_entity *entity = NULL;
7300 + LDP_ENTER(g->user_data, "ldp_cfg_entity_adj_getnext");
7302 + /* if an adj_index of zero is sent, get the index of
7303 + * the first adj in the list
7304 + */
7305 + if (!e->adj_index) {
7306 + this_one = MPLS_BOOL_TRUE;
7309 + mpls_lock_get(g->global_lock); /* LOCK */
7311 + if (ldp_global_find_entity_index(g, e->index, &entity) == MPLS_SUCCESS) {
7312 + adj = MPLS_LIST_HEAD(&entity->adj_root);
7313 + while (adj) {
7314 + if (this_one == MPLS_BOOL_TRUE) {
7315 + adj_next = adj;
7316 + break;
7319 + /* since the entities are sort in the list ... */
7320 + if (adj->index > e->adj_index) {
7321 + break;
7322 + } else if (adj->index == e->adj_index) {
7323 + this_one = MPLS_BOOL_TRUE;
7325 + adj = MPLS_LIST_NEXT(&entity->adj_root, adj, _entity);
7328 + mpls_lock_release(g->global_lock); /* UNLOCK */
7330 + if (adj_next) {
7331 + e->adj_index = adj_next->index;
7332 + r = MPLS_SUCCESS;
7335 + LDP_EXIT(g->user_data, "ldp_cfg_entity_adj_getnext");
7336 + return r;
7339 +/******************* INTERFACE **********************/
7341 +mpls_return_enum ldp_cfg_if_get(mpls_cfg_handle handle, ldp_if * i, uint32_t flag)
7343 + ldp_global *global = (ldp_global *) handle;
7344 + ldp_if *iff = NULL;
7345 + mpls_return_enum retval = MPLS_FAILURE;
7347 + MPLS_ASSERT(global !=NULL && i != NULL);
7349 + LDP_ENTER(global->user_data, "ldp_cfg_if_get");
7351 + mpls_lock_get(global->global_lock); /* LOCK */
7353 + if (flag & LDP_IF_CFG_BY_INDEX) {
7354 + ldp_global_find_if_index(global, i->index, &iff);
7355 + } else {
7356 + iff = ldp_global_find_if_handle(global, i->handle);
7358 + if (!iff)
7359 + goto ldp_cfg_if_get_end;
7361 + if (flag & LDP_IF_CFG_LABEL_SPACE) {
7362 + i->label_space = iff->label_space;
7364 + if (flag & LDP_IF_CFG_ENTITY_INDEX) {
7365 + i->entity_index = iff->entity ? iff->entity->index : 0;
7367 + if (flag & LDP_IF_CFG_OPER_STATE) {
7368 + i->oper_state = iff->oper_state;
7370 + if (flag & LDP_IF_CFG_HANDLE) {
7371 + memcpy(&i->handle, &iff->handle, sizeof(mpls_if_handle));
7373 + retval = MPLS_SUCCESS;
7375 +ldp_cfg_if_get_end:
7376 + mpls_lock_release(global->global_lock); /* UNLOCK */
7378 + LDP_EXIT(global->user_data, "ldp_cfg_if_get");
7380 + return retval;
7383 +mpls_return_enum ldp_cfg_if_getnext(mpls_cfg_handle handle, ldp_if * i,
7384 + uint32_t flag)
7386 + ldp_global *g = (ldp_global *) handle;
7387 + ldp_if *iff = NULL;
7388 + mpls_return_enum r = MPLS_FAILURE;
7389 + mpls_bool done = MPLS_BOOL_FALSE;
7390 + int index;
7392 + LDP_ENTER(g->user_data, "ldp_cfg_if_getnext");
7394 + if (i->index == 0) {
7395 + index = 1;
7396 + } else {
7397 + index = i->index + 1;
7400 + mpls_lock_get(g->global_lock); /* LOCK */
7401 + while (done == MPLS_BOOL_FALSE) {
7402 + switch ((r = ldp_global_find_if_index(g, index, &iff))) {
7403 + case MPLS_SUCCESS:
7404 + case MPLS_END_OF_LIST:
7405 + done = MPLS_BOOL_TRUE;
7406 + break;
7407 + case MPLS_FAILURE:
7408 + break;
7409 + default:
7410 + MPLS_ASSERT(0);
7412 + index++;
7414 + mpls_lock_release(g->global_lock); /* UNLOCK */
7416 + if (r == MPLS_SUCCESS) {
7417 + i->index = iff->index;
7418 + LDP_EXIT(g->user_data, "ldp_cfg_if_getnext");
7419 + return ldp_cfg_if_get(g, i, flag);
7421 + LDP_EXIT(g->user_data, "ldp_cfg_if_getnext");
7422 + return r;
7425 +mpls_return_enum ldp_cfg_if_test(mpls_cfg_handle handle, ldp_if * i,
7426 + uint32_t flag)
7428 + ldp_global *global = (ldp_global *) handle;
7429 + ldp_if *iff = NULL;
7430 + mpls_return_enum retval = MPLS_FAILURE;
7432 + MPLS_ASSERT(global !=NULL && i != NULL);
7434 + LDP_ENTER(global->user_data, "ldp_cfg_if_test");
7436 + mpls_lock_get(global->global_lock); /* LOCK */
7438 + if (!(flag & LDP_CFG_ADD)) {
7439 + ldp_global_find_if_index(global, i->index, &iff);
7440 + } else {
7441 + retval = MPLS_SUCCESS;
7442 + goto ldp_cfg_if_test_end;
7445 + if ((!iff) || ((ldp_if_is_active(iff) == MPLS_BOOL_TRUE) &&
7446 + (flag & LDP_IF_CFG_WHEN_DOWN))) {
7447 + goto ldp_cfg_if_test_end;
7450 + if (flag & LDP_CFG_DEL) {
7451 + if (iff->entity != NULL) {
7452 + goto ldp_cfg_if_test_end;
7455 + retval = MPLS_SUCCESS;
7457 +ldp_cfg_if_test_end:
7458 + mpls_lock_release(global->global_lock); /* UNLOCK */
7460 + LDP_EXIT(global->user_data, "ldp_cfg_if_test");
7462 + return retval;
7465 +mpls_return_enum ldp_cfg_if_set(mpls_cfg_handle handle, ldp_if * i, uint32_t flag)
7467 + ldp_global *global = (ldp_global*)handle;
7468 + ldp_if *iff = NULL;
7469 + ldp_addr *ap;
7470 + ldp_nexthop *np;
7471 + mpls_return_enum retval = MPLS_FAILURE;
7473 + MPLS_ASSERT(global !=NULL && i != NULL);
7475 + LDP_ENTER(global->user_data, "ldp_cfg_if_set");
7477 + mpls_lock_get(global->global_lock); /* LOCK */
7479 + if (flag & LDP_CFG_ADD) {
7480 + /* duplicate interface handles are not allowed */
7481 + /* ADDs require a valid interface handle */
7482 + if ((iff = ldp_global_find_if_handle(global, i->handle)) != NULL) {
7483 + LDP_PRINT(global->user_data, "Duplicate interface exists");
7484 + goto ldp_cfg_if_set_end;
7486 + if (mpls_if_handle_verify(global->ifmgr_handle, i->handle) ==
7487 + MPLS_BOOL_FALSE) {
7488 + LDP_PRINT(global->user_data, "Invalid interface handle");
7489 + goto ldp_cfg_if_set_end;
7491 + if ((iff = ldp_if_create(global)) == NULL) {
7492 + LDP_PRINT(global->user_data, "Failure creating interface");
7493 + goto ldp_cfg_if_set_end;
7496 + /* copy the handle from the user */
7497 + iff->handle = i->handle;
7499 + /* search for addrs and nexthops that are waiting for this interface */
7500 + ap = MPLS_LIST_HEAD(&global->addr);
7501 + while (ap) {
7502 + if (ap->if_handle == iff->handle && (!MPLS_LIST_IN_LIST(ap, _if))) {
7503 + ldp_if_add_addr(iff, ap);
7505 + ap = MPLS_LIST_NEXT(&global->addr, ap, _global);
7508 + np = MPLS_LIST_HEAD(&global->nexthop);
7509 + while (np) {
7510 + if ((np->info.type & MPLS_NH_IF) &&
7511 + (np->info.if_handle == iff->handle) && (!MPLS_LIST_IN_LIST(np, _if))) {
7512 + ldp_if_add_nexthop(iff, np);
7514 + np = MPLS_LIST_NEXT(&global->nexthop, np, _global);
7517 + /* send the newly created index back to the user */
7518 + i->index = iff->index;
7519 + MPLS_REFCNT_HOLD(iff);
7521 + } else {
7522 + if (flag & LDP_IF_CFG_BY_INDEX) {
7523 + ldp_global_find_if_index(global, i->index, &iff);
7524 + } else {
7525 + iff = ldp_global_find_if_handle(global, i->handle);
7529 + /*
7530 + * if we can't find this interface or if the interface is active and
7531 + * we are trying to change propertises that can not be changed on a
7532 + * active interface
7533 + */
7534 + if ((!iff) || ((ldp_if_is_active(iff) == MPLS_BOOL_TRUE) &&
7535 + (flag & LDP_IF_CFG_WHEN_DOWN))) {
7536 + goto ldp_cfg_if_set_end;
7539 + if (flag & LDP_IF_CFG_LABEL_SPACE) {
7540 + iff->label_space = i->label_space;
7543 + if (flag & LDP_CFG_DEL) {
7544 + /*
7545 + * if this interface is still attached to a entity that it is not ready
7546 + * to be removed
7547 + */
7548 + if (iff->entity != NULL) {
7549 + goto ldp_cfg_if_set_end;
7552 + np = MPLS_LIST_HEAD(&iff->nh_root);
7553 + while ((np = MPLS_LIST_HEAD(&iff->nh_root))) {
7554 + ldp_if_del_nexthop(global, iff, np);
7557 + ap = MPLS_LIST_HEAD(&iff->addr_root);
7558 + while ((ap = MPLS_LIST_HEAD(&iff->addr_root))) {
7559 + ldp_if_del_addr(global, iff, ap);
7562 + MPLS_REFCNT_RELEASE2(global, iff, ldp_if_delete);
7565 + global->configuration_sequence_number++;
7567 + retval = MPLS_SUCCESS;
7569 +ldp_cfg_if_set_end:
7570 + mpls_lock_release(global->global_lock); /* UNLOCK */
7572 + LDP_EXIT(global->user_data, "ldp_cfg_if_set");
7574 + return retval;
7577 +/******************* ATTR **********************/
7579 +mpls_return_enum ldp_cfg_attr_get(mpls_cfg_handle handle, ldp_attr * a,
7580 + uint32_t flag)
7582 + ldp_global *global = (ldp_global *) handle;
7583 + ldp_attr *attr = NULL;
7584 + mpls_return_enum retval = MPLS_FAILURE;
7586 + MPLS_ASSERT(global !=NULL && a != NULL);
7588 + LDP_ENTER(global->user_data, "ldp_cfg_attr_get");
7590 + mpls_lock_get(global->global_lock); /* LOCK */
7592 + if (ldp_global_find_attr_index(global, a->index, &attr) != MPLS_SUCCESS)
7593 + goto ldp_cfg_attr_get_end;
7595 + if (flag & LDP_ATTR_CFG_STATE) {
7596 + a->state = attr->state;
7598 + if (flag & LDP_ATTR_CFG_FEC) {
7599 + ldp_attr2ldp_attr(attr, a, LDP_ATTR_FEC);
7601 + if (flag & LDP_ATTR_CFG_LABEL) {
7602 + ldp_attr2ldp_attr(attr, a, LDP_ATTR_LABEL);
7604 + if (flag & LDP_ATTR_CFG_HOP_COUNT) {
7605 + ldp_attr2ldp_attr(attr, a, LDP_ATTR_HOPCOUNT);
7607 + if (flag & LDP_ATTR_CFG_PATH) {
7608 + ldp_attr2ldp_attr(attr, a, LDP_ATTR_PATH);
7610 + if (flag & LDP_ATTR_CFG_SESSION_INDEX) {
7611 + a->session_index = (attr->session) ? (attr->session->index) : 0;
7613 + if (flag & LDP_ATTR_CFG_INLABEL_INDEX) {
7614 + a->inlabel_index = (attr->inlabel) ? (attr->inlabel->index) : 0;
7616 + if (flag & LDP_ATTR_CFG_OUTLABEL_INDEX) {
7617 + a->outlabel_index = (attr->outlabel) ? (attr->outlabel->index) : 0;
7619 + if (flag & LDP_ATTR_CFG_INGRESS) {
7620 + a->ingress = attr->ingress;
7622 + retval = MPLS_SUCCESS;
7624 +ldp_cfg_attr_get_end:
7625 + mpls_lock_release(global->global_lock); /* UNLOCK */
7627 + LDP_EXIT(global->user_data, "ldp_cfg_attr_get");
7629 + return retval;
7632 +mpls_return_enum ldp_cfg_attr_getnext(mpls_cfg_handle handle, ldp_attr * a,
7633 + uint32_t flag)
7635 + ldp_global *g = (ldp_global *) handle;
7636 + ldp_attr *attr = NULL;
7637 + mpls_return_enum r = MPLS_FAILURE;
7638 + mpls_bool done = MPLS_BOOL_FALSE;
7639 + int index;
7641 + LDP_ENTER(g->user_data, "ldp_cfg_attr_getnext");
7643 + if (a->index == 0) {
7644 + index = 1;
7645 + } else {
7646 + index = a->index + 1;
7649 + mpls_lock_get(g->global_lock); /* LOCK */
7650 + while (done == MPLS_BOOL_FALSE) {
7651 + switch ((r = ldp_global_find_attr_index(g, index, &attr))) {
7652 + case MPLS_SUCCESS:
7653 + case MPLS_END_OF_LIST:
7654 + done = MPLS_BOOL_TRUE;
7655 + break;
7656 + case MPLS_FAILURE:
7657 + break;
7658 + default:
7659 + MPLS_ASSERT(0);
7661 + index++;
7663 + mpls_lock_release(g->global_lock); /* UNLOCK */
7665 + if (r == MPLS_SUCCESS) {
7666 + a->index = attr->index;
7667 + LDP_EXIT(g->user_data, "ldp_cfg_attr_getnext");
7668 + return ldp_cfg_attr_get(g, a, flag);
7670 + LDP_EXIT(g->user_data, "ldp_cfg_attr_getnext");
7671 + return r;
7674 +/******************* PEER **********************/
7676 +mpls_return_enum ldp_cfg_peer_get(mpls_cfg_handle handle, ldp_peer * p,
7677 + uint32_t flag)
7679 + ldp_global *global = (ldp_global *) handle;
7680 + ldp_peer *peer = NULL;
7681 + mpls_return_enum retval = MPLS_FAILURE;
7683 + MPLS_ASSERT(global !=NULL && p != NULL);
7685 + LDP_ENTER(global->user_data, "ldp_cfg_peer_get");
7687 + mpls_lock_get(global->global_lock); /* LOCK */
7689 + if (ldp_global_find_peer_index(global, p->index, &peer) != MPLS_SUCCESS)
7690 + goto ldp_cfg_peer_get_end;
7692 + if (flag & LDP_PEER_CFG_LABEL_SPACE) {
7693 + p->label_space = peer->label_space;
7695 + if (flag & LDP_PEER_CFG_TARGET_ROLE) {
7696 + p->target_role = peer->target_role;
7698 + if (flag & LDP_PEER_CFG_DEST_ADDR) {
7699 + memcpy(&p->dest.addr, &peer->dest.addr, sizeof(mpls_inet_addr));
7701 + if (flag & LDP_PEER_CFG_ENTITY_INDEX) {
7702 + p->entity_index = peer->entity->index;
7704 + if (flag & LDP_PEER_CFG_OPER_STATE) {
7705 + p->oper_state = peer->oper_state;
7707 + if (flag & LDP_PEER_CFG_PEER_NAME) {
7708 + strncpy(p->peer_name, peer->peer_name, MPLS_MAX_IF_NAME);
7710 + retval = MPLS_SUCCESS;
7712 +ldp_cfg_peer_get_end:
7713 + mpls_lock_release(global->global_lock); /* UNLOCK */
7715 + LDP_EXIT(global->user_data, "ldp_cfg_peer_get");
7717 + return retval;
7720 +mpls_return_enum ldp_cfg_peer_getnext(mpls_cfg_handle handle, ldp_peer * p,
7721 + uint32_t flag)
7723 + ldp_global *g = (ldp_global *) handle;
7724 + ldp_peer *peer = NULL;
7725 + mpls_return_enum r = MPLS_FAILURE;
7726 + mpls_bool done = MPLS_BOOL_FALSE;
7727 + int index;
7729 + LDP_ENTER(g->user_data, "ldp_cfg_peer_getnext");
7731 + if (p->index == 0) {
7732 + index = 1;
7733 + } else {
7734 + index = p->index + 1;
7737 + mpls_lock_get(g->global_lock); /* LOCK */
7738 + while (done == MPLS_BOOL_FALSE) {
7739 + switch ((r = ldp_global_find_peer_index(g, index, &peer))) {
7740 + case MPLS_SUCCESS:
7741 + case MPLS_END_OF_LIST:
7742 + done = MPLS_BOOL_TRUE;
7743 + break;
7744 + case MPLS_FAILURE:
7745 + break;
7746 + default:
7747 + MPLS_ASSERT(0);
7749 + index++;
7751 + mpls_lock_release(g->global_lock); /* UNLOCK */
7753 + if (r == MPLS_SUCCESS) {
7754 + p->index = peer->index;
7755 + LDP_EXIT(g->user_data, "ldp_cfg_peer_getnext");
7756 + return ldp_cfg_peer_get(g, p, flag);
7758 + LDP_EXIT(g->user_data, "ldp_cfg_peer_getnext");
7759 + return r;
7762 +mpls_return_enum ldp_cfg_peer_test(mpls_cfg_handle handle, ldp_peer * p,
7763 + uint32_t flag)
7765 + // ldp_global* g = (ldp_global*)handle;
7766 + return MPLS_SUCCESS;
7769 +mpls_return_enum ldp_cfg_peer_set(mpls_cfg_handle handle, ldp_peer * p,
7770 + uint32_t flag)
7772 + ldp_global *global = (ldp_global *) handle;
7773 + ldp_peer *peer = NULL;
7774 + mpls_return_enum retval = MPLS_FAILURE;
7776 + MPLS_ASSERT(global !=NULL && p != NULL);
7778 + LDP_ENTER(global->user_data, "ldp_cfg_peer_set");
7780 + mpls_lock_get(global->global_lock); /* LOCK */
7782 + if (flag & LDP_CFG_ADD) {
7783 + if ((peer = ldp_peer_create()) == NULL) {
7784 + goto ldp_cfg_peer_set_end;
7786 + p->index = peer->index;
7787 + _ldp_global_add_peer(global, peer);
7788 + } else {
7789 + ldp_global_find_peer_index(global, p->index, &peer);
7792 + if (peer == NULL) {
7793 + LDP_PRINT(global->user_data, "ldp_cfg_peer_set: no such peer\n");
7795 + goto ldp_cfg_peer_set_end;
7797 + if ((ldp_peer_is_active(peer) == MPLS_BOOL_TRUE) && (flag & LDP_PEER_CFG_WHEN_DOWN)) {
7798 + LDP_PRINT(global->user_data, "ldp_cfg_peer_set: peer is activer\n");
7800 + goto ldp_cfg_peer_set_end;
7803 + if (flag & LDP_CFG_DEL) {
7804 + if (peer->entity != NULL) {
7805 + LDP_PRINT(global->user_data,
7806 + "ldp_cfg_peer_set: not cleanup correctly is activer\n");
7808 + goto ldp_cfg_peer_set_end;
7811 + _ldp_global_del_peer(global, peer);
7813 + retval = MPLS_SUCCESS;
7814 + goto ldp_cfg_peer_set_end;
7816 + if (flag & LDP_PEER_CFG_LABEL_SPACE) {
7817 + peer->label_space = p->label_space;
7819 + if (flag & LDP_PEER_CFG_TARGET_ROLE) {
7820 + peer->target_role = p->target_role;
7822 + if (flag & LDP_PEER_CFG_DEST_ADDR) {
7823 + memcpy(&peer->dest.addr, &p->dest.addr, sizeof(mpls_inet_addr));
7825 + if (flag & LDP_PEER_CFG_PEER_NAME) {
7826 + LDP_PRINT(global->user_data, "ldp_cfg_peer_set: peer_name = %s\n",
7828 + p->peer_name);
7829 + strncpy(peer->peer_name, p->peer_name, MPLS_MAX_IF_NAME);
7831 + global->configuration_sequence_number++;
7833 + retval = MPLS_SUCCESS;
7835 +ldp_cfg_peer_set_end:
7836 + mpls_lock_release(global->global_lock); /* UNLOCK */
7838 + LDP_EXIT(global->user_data, "ldp_cfg_peer_set");
7840 + return retval;
7842 +/******************* FEC **********************/
7844 +mpls_return_enum ldp_cfg_fec_get(mpls_cfg_handle handle, mpls_fec * f,
7845 + uint32_t flag)
7847 + ldp_global *global = (ldp_global *) handle;
7848 + ldp_fec *fec = NULL;
7849 + mpls_return_enum retval = MPLS_FAILURE;
7851 + MPLS_ASSERT(global !=NULL && f != NULL);
7853 + LDP_ENTER(global->user_data, "ldp_cfg_fec_get");
7855 + mpls_lock_get(global->global_lock); /* LOCK */
7857 + if (flag & LDP_FEC_CFG_BY_INDEX) {
7858 + ldp_global_find_fec_index(global, f->index, &fec);
7859 + } else {
7860 + fec = ldp_fec_find(global, f);
7862 + if (!fec)
7863 + goto ldp_cfg_fec_get_end;
7865 + memcpy(f, &fec->info, sizeof(mpls_fec));
7866 + f->index = fec->index;
7867 + f->is_route = fec->is_route;
7868 + retval = MPLS_SUCCESS;
7870 +ldp_cfg_fec_get_end:
7871 + mpls_lock_release(global->global_lock); /* UNLOCK */
7873 + LDP_EXIT(global->user_data, "ldp_cfg_fec_get");
7875 + return retval;
7878 +mpls_return_enum ldp_cfg_fec_getnext(mpls_cfg_handle handle, mpls_fec * f,
7879 + uint32_t flag)
7881 + ldp_global *g = (ldp_global *) handle;
7882 + ldp_fec *fec = NULL;
7883 + mpls_return_enum r = MPLS_FAILURE;
7884 + mpls_bool done = MPLS_BOOL_FALSE;
7885 + int index;
7887 + LDP_ENTER(g->user_data, "ldp_cfg_fec_getnext");
7889 + if (f->index == 0) {
7890 + index = 1;
7891 + } else {
7892 + index = f->index + 1;
7895 + mpls_lock_get(g->global_lock); /* LOCK */
7896 + while (done == MPLS_BOOL_FALSE) {
7897 + switch ((r = ldp_global_find_fec_index(g, index, &fec))) {
7898 + case MPLS_SUCCESS:
7899 + case MPLS_END_OF_LIST:
7900 + done = MPLS_BOOL_TRUE;
7901 + break;
7902 + case MPLS_FAILURE:
7903 + break;
7904 + default:
7905 + MPLS_ASSERT(0);
7907 + index++;
7909 + mpls_lock_release(g->global_lock); /* UNLOCK */
7911 + if (r == MPLS_SUCCESS) {
7912 + f->index = fec->index;
7913 + LDP_EXIT(g->user_data, "ldp_cfg_fec_getnext");
7914 + return ldp_cfg_fec_get(g, f, flag);
7916 + LDP_EXIT(g->user_data, "ldp_cfg_fec_getnext");
7917 + return r;
7920 +mpls_return_enum ldp_cfg_fec_test(mpls_cfg_handle handle, mpls_fec * f,
7921 + uint32_t flag)
7923 + // ldp_global* g = (ldp_global*)handle;
7924 + return MPLS_SUCCESS;
7927 +mpls_return_enum ldp_cfg_fec_set(mpls_cfg_handle handle, mpls_fec * f,
7928 + uint32_t flag)
7930 + ldp_global *global = (ldp_global *) handle;
7931 + ldp_fec *fec = NULL;
7932 + mpls_return_enum retval = MPLS_FAILURE;
7934 + MPLS_ASSERT(global != NULL && f != NULL);
7936 + LDP_ENTER(global->user_data, "ldp_cfg_fec_set");
7938 + mpls_lock_get(global->global_lock); /* LOCK */
7940 + if (flag & LDP_CFG_ADD) {
7941 + if ((fec = ldp_fec_find(global, f))) {
7942 + if (fec->is_route == MPLS_BOOL_TRUE) {
7943 + goto ldp_cfg_fec_set_end;
7945 + } else {
7946 + if ((fec = ldp_fec_create(global, f)) == NULL) {
7947 + goto ldp_cfg_fec_set_end;
7950 + fec->is_route = MPLS_BOOL_TRUE;
7951 + MPLS_REFCNT_HOLD(fec);
7952 + f->index = fec->index;
7953 + } else {
7954 + if (flag & LDP_FEC_CFG_BY_INDEX) {
7955 + ldp_global_find_fec_index(global, f->index, &fec);
7956 + } else {
7957 + fec = ldp_fec_find(global, f);
7961 + if (fec == NULL) {
7962 + LDP_PRINT(global->user_data, "ldp_cfg_fec_set: no such fec\n");
7963 + goto ldp_cfg_fec_set_end;
7966 + if (flag & LDP_CFG_DEL) {
7967 + /*
7968 + * we can only delete the fec if all of the nexthops have been removed
7969 + */
7970 + if (!MPLS_LIST_EMPTY(&fec->nh_root)) {
7971 + goto ldp_cfg_fec_set_end;
7974 + fec->is_route = MPLS_BOOL_FALSE;
7976 + /*
7977 + * we hold the last refcnt, this should result in a call to
7978 + * ldp_fec_delete
7979 + */
7980 + MPLS_REFCNT_RELEASE2(global, fec, ldp_fec_delete);
7983 + retval = MPLS_SUCCESS;
7985 +ldp_cfg_fec_set_end:
7986 + mpls_lock_release(global->global_lock); /* UNLOCK */
7988 + LDP_EXIT(global->user_data, "ldp_cfg_fec_set");
7989 + return retval;
7992 +mpls_return_enum ldp_cfg_fec_nexthop_get(mpls_cfg_handle handle, mpls_fec * f,
7993 + mpls_nexthop *n, uint32_t flag)
7995 + ldp_global *global = (ldp_global *) handle;
7996 + ldp_fec *fec = NULL;
7997 + ldp_nexthop *nh = NULL;
7998 + mpls_return_enum retval = MPLS_FAILURE;
8000 + MPLS_ASSERT(global !=NULL && f != NULL);
8002 + LDP_ENTER(global->user_data, "ldp_cfg_fec_nexthop_get");
8004 + mpls_lock_get(global->global_lock); /* LOCK */
8006 + if (flag & LDP_FEC_CFG_BY_INDEX) {
8007 + ldp_global_find_fec_index(global, f->index, &fec);
8008 + } else {
8009 + fec = ldp_fec_find(global, f);
8011 + if (!fec)
8012 + goto ldp_cfg_fec_nexthop_get_end;
8014 + if (flag & LDP_FEC_NEXTHOP_CFG_BY_INDEX) {
8015 + ldp_fec_find_nexthop_index(fec, n->index, &nh);
8016 + } else {
8017 + nh = ldp_fec_nexthop_find(fec, n);
8019 + if (!nh)
8020 + goto ldp_cfg_fec_nexthop_get_end;
8022 + memcpy(n, &nh->info, sizeof(mpls_nexthop));
8023 + n->index = nh->index;
8024 + retval = MPLS_SUCCESS;
8026 +ldp_cfg_fec_nexthop_get_end:
8027 + mpls_lock_release(global->global_lock); /* UNLOCK */
8029 + LDP_EXIT(global->user_data, "ldp_cfg_fec_nexthop_get");
8031 + return retval;
8034 +mpls_return_enum ldp_cfg_fec_nexthop_getnext(mpls_cfg_handle handle,
8035 + mpls_fec * f, mpls_nexthop *n, uint32_t flag)
8037 + ldp_global *global = (ldp_global *) handle;
8038 + ldp_fec *fec = NULL;
8039 + ldp_nexthop *nh = NULL;
8040 + mpls_return_enum r = MPLS_FAILURE;
8041 + mpls_bool done = MPLS_BOOL_FALSE;
8042 + int index;
8044 + LDP_ENTER(global->user_data, "ldp_cfg_fec_nexthop_getnext");
8046 + if (n->index == 0) {
8047 + index = 1;
8048 + } else {
8049 + index = n->index + 1;
8052 + mpls_lock_get(global->global_lock); /* LOCK */
8054 + if (flag & LDP_FEC_CFG_BY_INDEX) {
8055 + ldp_global_find_fec_index(global, f->index, &fec);
8056 + } else {
8057 + fec = ldp_fec_find(global, f);
8059 + if (!fec)
8060 + goto ldp_cfg_fec_nexthop_getnext_end;
8062 + while (done == MPLS_BOOL_FALSE) {
8063 + switch ((r = ldp_fec_find_nexthop_index(fec, index, &nh))) {
8064 + case MPLS_SUCCESS:
8065 + case MPLS_END_OF_LIST:
8066 + done = MPLS_BOOL_TRUE;
8067 + break;
8068 + case MPLS_FAILURE:
8069 + break;
8070 + default:
8071 + MPLS_ASSERT(0);
8073 + index++;
8075 + mpls_lock_release(global->global_lock); /* UNLOCK */
8077 + if (r == MPLS_SUCCESS) {
8078 + n->index = nh->index;
8079 + LDP_EXIT(global->user_data, "ldp_cfg_fec_nexthop_getnext");
8080 + return ldp_cfg_fec_nexthop_get(global, f, n, flag);
8083 +ldp_cfg_fec_nexthop_getnext_end:
8085 + LDP_EXIT(global->user_data, "ldp_cfg_fec_nexthop_getnext");
8086 + return r;
8089 +mpls_return_enum ldp_cfg_fec_nexthop_test(mpls_cfg_handle handle, mpls_fec * f,
8090 + mpls_nexthop *n, uint32_t flag)
8092 + // ldp_global* g = (ldp_global*)handle;
8093 + return MPLS_SUCCESS;
8096 +mpls_return_enum ldp_cfg_fec_nexthop_set(mpls_cfg_handle handle, mpls_fec * f,
8097 + mpls_nexthop *n, uint32_t flag)
8099 + ldp_global *global = (ldp_global *) handle;
8100 + ldp_fec *fec = NULL;
8101 + ldp_nexthop *nh = NULL;
8102 + mpls_return_enum retval = MPLS_FAILURE;
8104 + MPLS_ASSERT(global != NULL && f != NULL && n != NULL);
8106 + LDP_ENTER(global->user_data, "ldp_cfg_fec_nexthop_set");
8108 + mpls_lock_get(global->global_lock); /* LOCK */
8110 + if (flag & LDP_FEC_CFG_BY_INDEX) {
8111 + ldp_global_find_fec_index(global, f->index, &fec);
8112 + } else {
8113 + fec = ldp_fec_find(global, f);
8115 + if (!fec)
8116 + goto ldp_cfg_fec_nexthop_set_end;
8118 + if (flag & LDP_CFG_ADD) {
8119 + if (ldp_fec_nexthop_find(fec, n) ||
8120 + (nh = ldp_nexthop_create(global, n)) == NULL) {
8121 + goto ldp_cfg_fec_nexthop_set_end;
8123 + n->index = nh->index;
8124 + ldp_fec_add_nexthop(global, fec, nh);
8125 + ldp_fec_process_add(global, fec, nh, NULL);
8126 + } else {
8127 + if (flag & LDP_FEC_NEXTHOP_CFG_BY_INDEX) {
8128 + ldp_fec_find_nexthop_index(fec, n->index, &nh);
8129 + } else {
8130 + nh = ldp_fec_nexthop_find(fec, n);
8134 + if (nh == NULL) {
8135 + LDP_PRINT(global->user_data, "ldp_cfg_fec_nexthop_set: no such nh\n");
8136 + goto ldp_cfg_fec_nexthop_set_end;
8139 + if (flag & LDP_CFG_DEL) {
8140 + MPLS_REFCNT_HOLD(nh);
8141 + ldp_fec_del_nexthop(global, fec, nh);
8142 + if (ldp_fec_process_change(global, fec, MPLS_LIST_HEAD(&fec->nh_root),
8143 + nh, NULL) != MPLS_SUCCESS) {
8144 + MPLS_ASSERT(0);
8146 + MPLS_REFCNT_RELEASE2(global, nh, ldp_nexthop_delete);
8149 + retval = MPLS_SUCCESS;
8151 +ldp_cfg_fec_nexthop_set_end:
8152 + mpls_lock_release(global->global_lock); /* UNLOCK */
8154 + LDP_EXIT(global->user_data, "ldp_cfg_fec_nexthop_set");
8156 + return retval;
8159 +/******************* ADDR **********************/
8161 +mpls_return_enum ldp_cfg_addr_get(mpls_cfg_handle handle, ldp_addr * a,
8162 + uint32_t flag)
8164 + ldp_global *global = (ldp_global *) handle;
8165 + ldp_session *session = NULL;
8166 + ldp_nexthop *nexthop = NULL;
8167 + ldp_addr *addr = NULL;
8168 + mpls_return_enum retval = MPLS_FAILURE;
8170 + MPLS_ASSERT(global !=NULL && a != NULL);
8172 + LDP_ENTER(global->user_data, "ldp_cfg_addr_get");
8174 + mpls_lock_get(global->global_lock); /* LOCK */
8176 + ldp_global_find_addr_index(global, a->index, &addr);
8178 + if (!addr)
8179 + goto ldp_cfg_addr_get_end;
8181 + memcpy(&a->address, &addr->address, sizeof(mpls_inet_addr));
8182 + a->index = addr->index;
8184 + if (addr->session) {
8185 + a->session_index = addr->session->index;
8188 + if ((nexthop = MPLS_LIST_HEAD(&addr->nh_root))) {
8189 + a->nexthop_index = nexthop->index;
8192 + if (addr->iff) {
8193 + a->if_index = addr->iff->index;
8196 + retval = MPLS_SUCCESS;
8198 +ldp_cfg_addr_get_end:
8199 + mpls_lock_release(global->global_lock); /* UNLOCK */
8201 + LDP_EXIT(global->user_data, "ldp_cfg_addr_get");
8203 + return retval;
8206 +mpls_return_enum ldp_cfg_addr_getnext(mpls_cfg_handle handle, ldp_addr *a,
8207 + uint32_t flag)
8209 + ldp_global *global = (ldp_global *) handle;
8210 + ldp_addr *addr = NULL;
8211 + mpls_return_enum r = MPLS_FAILURE;
8212 + mpls_bool done = MPLS_BOOL_FALSE;
8213 + int index;
8215 + LDP_ENTER(global->user_data, "ldp_cfg_addr_getnext");
8217 + if (a->index == 0) {
8218 + index = 1;
8219 + } else {
8220 + index = a->index + 1;
8223 + mpls_lock_get(global->global_lock); /* LOCK */
8225 + while (done == MPLS_BOOL_FALSE) {
8226 + switch ((r = ldp_global_find_addr_index(global, index, &addr))) {
8227 + case MPLS_SUCCESS:
8228 + case MPLS_END_OF_LIST:
8229 + done = MPLS_BOOL_TRUE;
8230 + break;
8231 + case MPLS_FAILURE:
8232 + break;
8233 + default:
8234 + MPLS_ASSERT(0);
8236 + index++;
8238 + mpls_lock_release(global->global_lock); /* UNLOCK */
8240 + if (r == MPLS_SUCCESS) {
8241 + a->index = addr->index;
8242 + LDP_EXIT(global->user_data, "ldp_cfg_addr_getnext");
8243 + return ldp_cfg_addr_get(global, a, flag);
8246 + LDP_EXIT(global->user_data, "ldp_cfg_addr_getnext");
8247 + return r;
8250 +/******************* IF ADDR **********************/
8252 +mpls_return_enum ldp_cfg_if_addr_get(mpls_cfg_handle handle, ldp_if * i,
8253 + ldp_addr * a, uint32_t flag)
8255 + ldp_global *global = (ldp_global *) handle;
8256 + ldp_addr *addr = NULL;
8257 + ldp_if *iff = NULL;
8258 + mpls_return_enum retval = MPLS_FAILURE;
8260 + MPLS_ASSERT(global !=NULL && i != NULL && a != NULL);
8262 + LDP_ENTER(global->user_data, "ldp_cfg_if_addr_get");
8264 + mpls_lock_get(global->global_lock); /* LOCK */
8266 + if (flag & LDP_IF_CFG_BY_INDEX) {
8267 + ldp_global_find_if_index(global, i->index, &iff);
8268 + } else {
8269 + iff = ldp_global_find_if_handle(global, i->handle);
8271 + if (!iff)
8272 + goto ldp_cfg_if_addr_get_end;
8274 + if (flag & LDP_IF_ADDR_CFG_BY_INDEX) {
8275 + ldp_if_find_addr_index(iff, a->index, &addr);
8276 + } else {
8277 + addr = ldp_if_addr_find(iff, &a->address);
8279 + if (!addr)
8280 + goto ldp_cfg_if_addr_get_end;
8282 + memcpy(&a->address, &addr->address, sizeof(mpls_inet_addr));
8283 + a->index = addr->index;
8285 + retval = MPLS_SUCCESS;
8287 +ldp_cfg_if_addr_get_end:
8288 + mpls_lock_release(global->global_lock); /* UNLOCK */
8290 + LDP_EXIT(global->user_data, "ldp_cfg_if_addr_get");
8292 + return retval;
8295 +mpls_return_enum ldp_cfg_if_addr_getnext(mpls_cfg_handle handle,
8296 + ldp_if * i, ldp_addr *a, uint32_t flag)
8298 + ldp_global *global = (ldp_global *) handle;
8299 + ldp_if *iff = NULL;
8300 + ldp_addr *addr = NULL;
8301 + mpls_return_enum r = MPLS_FAILURE;
8302 + mpls_bool done = MPLS_BOOL_FALSE;
8303 + int index;
8305 + LDP_ENTER(global->user_data, "ldp_cfg_if_addr_getnext");
8307 + if (a->index == 0) {
8308 + index = 1;
8309 + } else {
8310 + index = a->index + 1;
8313 + mpls_lock_get(global->global_lock); /* LOCK */
8315 + if (flag & LDP_IF_CFG_BY_INDEX) {
8316 + ldp_global_find_if_index(global, i->index, &iff);
8317 + } else {
8318 + iff = ldp_global_find_if_handle(global, i->handle);
8320 + if (!iff)
8321 + goto ldp_cfg_if_addr_getnext_end;
8323 + while (done == MPLS_BOOL_FALSE) {
8324 + switch ((r = ldp_if_find_addr_index(iff, index, &addr))) {
8325 + case MPLS_SUCCESS:
8326 + case MPLS_END_OF_LIST:
8327 + done = MPLS_BOOL_TRUE;
8328 + break;
8329 + case MPLS_FAILURE:
8330 + break;
8331 + default:
8332 + MPLS_ASSERT(0);
8334 + index++;
8336 + mpls_lock_release(global->global_lock); /* UNLOCK */
8338 + if (r == MPLS_SUCCESS) {
8339 + a->index = addr->index;
8340 + LDP_EXIT(global->user_data, "ldp_cfg_if_addr_getnext");
8341 + return ldp_cfg_if_addr_get(global, i, a, flag);
8344 +ldp_cfg_if_addr_getnext_end:
8346 + LDP_EXIT(global->user_data, "ldp_cfg_if_addr_getnext");
8347 + return r;
8350 +mpls_return_enum ldp_cfg_if_addr_set(mpls_cfg_handle handle, ldp_if * i,
8351 + ldp_addr *a, uint32_t flag)
8353 + ldp_global *global = (ldp_global *) handle;
8354 + ldp_if *iff = NULL;
8355 + ldp_addr *addr = NULL;
8356 + mpls_return_enum retval = MPLS_FAILURE;
8358 + MPLS_ASSERT(global != NULL && i != NULL && a != NULL);
8360 + LDP_ENTER(global->user_data, "ldp_cfg_if_addr_set");
8362 + mpls_lock_get(global->global_lock); /* LOCK */
8364 + if (flag & LDP_IF_CFG_BY_INDEX) {
8365 + ldp_global_find_if_index(global, i->index, &iff);
8366 + } else {
8367 + iff = ldp_global_find_if_handle(global, i->handle);
8369 + if (!iff) {
8370 + LDP_PRINT(global->user_data, "ldp_cfg_if_addr_set: no such iff\n");
8371 + goto ldp_cfg_if_addr_set_end;
8374 + if (flag & LDP_CFG_ADD) {
8375 + if (ldp_if_addr_find(iff, &a->address) || ((addr = ldp_addr_create(global,
8376 + &a->address)) == NULL)) {
8377 + goto ldp_cfg_if_addr_set_end;
8379 + a->index = addr->index;
8380 + ldp_if_add_addr(iff, addr);
8381 + ldp_addr_process_add(global, addr);
8382 + } else {
8383 + if (flag & LDP_IF_ADDR_CFG_BY_INDEX) {
8384 + ldp_if_find_addr_index(iff, a->index, &addr);
8385 + } else {
8386 + addr = ldp_if_addr_find(iff, &a->address);
8390 + if (addr == NULL) {
8391 + LDP_PRINT(global->user_data, "ldp_cfg_if_addr_set: no such addr\n");
8392 + goto ldp_cfg_if_addr_set_end;
8395 + if (flag & LDP_CFG_DEL) {
8396 + ldp_addr_process_remove(global, addr);
8397 + ldp_if_del_addr(global, iff, addr);
8400 + retval = MPLS_SUCCESS;
8402 +ldp_cfg_if_addr_set_end:
8403 + mpls_lock_release(global->global_lock); /* UNLOCK */
8405 + LDP_EXIT(global->user_data, "ldp_cfg_if_addr_set");
8407 + return retval;
8410 +/******************* ADJACENCY **********************/
8412 +mpls_return_enum ldp_cfg_adj_get(mpls_cfg_handle handle, ldp_adj * a,
8413 + uint32_t flag)
8415 + ldp_global *global = (ldp_global *) handle;
8416 + ldp_adj *adj = NULL;
8417 + mpls_return_enum retval = MPLS_FAILURE;
8419 + MPLS_ASSERT(global != NULL && a != NULL);
8421 + LDP_ENTER(global->user_data, "ldp_cfg_adj_get");
8423 + mpls_lock_get(global->global_lock); /* LOCK */
8425 + if (ldp_global_find_adj_index(global, a->index, &adj) != MPLS_SUCCESS)
8426 + goto ldp_cfg_adj_get_end;
8428 + if (flag & LDP_ADJ_CFG_REMOTE_TRADDR) {
8429 + memcpy(&a->remote_transport_address, &adj->remote_transport_address,
8430 + sizeof(mpls_inet_addr));
8432 + if (flag & LDP_ADJ_CFG_REMOTE_SRCADDR) {
8433 + memcpy(&a->remote_source_address, &adj->remote_source_address,
8434 + sizeof(mpls_inet_addr));
8436 + if (flag & LDP_ADJ_CFG_REMOTE_LSRADDR) {
8437 + memcpy(&a->remote_lsr_address, &adj->remote_lsr_address,
8438 + sizeof(mpls_inet_addr));
8440 + if (flag & LDP_ADJ_CFG_REMOTE_CSN) {
8441 + a->remote_csn = adj->remote_csn;
8443 + if (flag & LDP_ADJ_CFG_REMOTE_LABELSPACE) {
8444 + a->remote_label_space = adj->remote_label_space;
8446 + if (flag & LDP_ADJ_CFG_REMOTE_HELLOTIME) {
8447 + a->remote_hellotime = adj->remote_hellotime;
8449 + if (flag & LDP_ADJ_CFG_ENTITY_INDEX) {
8450 + a->entity_index = adj->entity ? adj->entity->index : 0;
8452 + if (flag & LDP_ADJ_CFG_REMOTE_SESSION_INDEX) {
8453 + a->session_index = (adj->session) ? (adj->session->index) : 0;
8455 + if (flag & LDP_ADJ_CFG_ROLE) {
8456 + a->role = adj->role;
8458 + retval = MPLS_SUCCESS;
8460 +ldp_cfg_adj_get_end:
8462 + mpls_lock_release(global->global_lock); /* UNLOCK */
8464 + LDP_EXIT(global->user_data, "ldp_cfg_adj_get");
8466 + return retval;
8469 +mpls_return_enum ldp_cfg_adj_getnext(mpls_cfg_handle handle, ldp_adj * a,
8470 + uint32_t flag)
8472 + ldp_global *g = (ldp_global *) handle;
8473 + ldp_adj *adj = NULL;
8474 + mpls_return_enum r = MPLS_FAILURE;
8475 + mpls_bool done = MPLS_BOOL_FALSE;
8476 + int index;
8478 + LDP_ENTER(g->user_data, "ldp_cfg_adj_getnext");
8480 + if (a->index == 0) {
8481 + index = 1;
8482 + } else {
8483 + index = a->index + 1;
8486 + mpls_lock_get(g->global_lock); /* LOCK */
8487 + while (done == MPLS_BOOL_FALSE) {
8488 + switch ((r = ldp_global_find_adj_index(g, index, &adj))) {
8489 + case MPLS_SUCCESS:
8490 + case MPLS_END_OF_LIST:
8491 + done = MPLS_BOOL_TRUE;
8492 + break;
8493 + case MPLS_FAILURE:
8494 + break;
8495 + default:
8496 + MPLS_ASSERT(0);
8498 + index++;
8500 + mpls_lock_release(g->global_lock); /* UNLOCK */
8502 + if (r == MPLS_SUCCESS) {
8503 + a->index = adj->index;
8504 + LDP_EXIT(g->user_data, "ldp_cfg_adj_getnext");
8505 + return ldp_cfg_adj_get(g, a, flag);
8507 + LDP_EXIT(g->user_data, "ldp_cfg_adj_getnext");
8508 + return r;
8511 +/******************* SESSION **********************/
8513 +mpls_return_enum ldp_cfg_session_get(mpls_cfg_handle handle, ldp_session * s,
8514 + uint32_t flag)
8516 + ldp_global *global = (ldp_global *) handle;
8517 + ldp_session *session = NULL;
8518 + mpls_return_enum retval = MPLS_FAILURE;
8520 + MPLS_ASSERT(global !=NULL && s != NULL);
8522 + LDP_ENTER(global->user_data, "ldp_cfg_session_get");
8524 + mpls_lock_get(global->global_lock); /* LOCK */
8526 + if (ldp_global_find_session_index(global, s->index, &session) != MPLS_SUCCESS)
8527 + goto ldp_cfg_session_get_end;
8529 + if (flag & LDP_SESSION_CFG_STATE) {
8530 + s->state = session->state;
8532 + if (flag & LDP_SESSION_CFG_OPER_UP) {
8533 + s->oper_up = session->oper_up;
8535 + if (flag & LDP_SESSION_CFG_MAX_PDU) {
8536 + s->oper_max_pdu = session->oper_max_pdu;
8538 + if (flag & LDP_SESSION_CFG_KEEPALIVE) {
8539 + s->oper_keepalive = session->oper_keepalive;
8541 + if (flag & LDP_SESSION_CFG_PATH_LIMIT) {
8542 + s->oper_path_vector_limit = session->oper_path_vector_limit;
8544 + if (flag & LDP_SESSION_CFG_DIST_MODE) {
8545 + s->oper_distribution_mode = session->oper_distribution_mode;
8547 + if (flag & LDP_SESSION_CFG_LOOP_DETECTION) {
8548 + s->oper_loop_detection = session->oper_loop_detection;
8550 + if (flag & LDP_SESSION_CFG_REMOTE_MAX_PDU) {
8551 + s->remote_max_pdu = session->remote_max_pdu;
8553 + if (flag & LDP_SESSION_CFG_REMOTE_KEEPALIVE) {
8554 + s->remote_keepalive = session->remote_keepalive;
8556 + if (flag & LDP_SESSION_CFG_REMOTE_PATH_LIMIT) {
8557 + s->remote_path_vector_limit = session->remote_path_vector_limit;
8559 + if (flag & LDP_SESSION_CFG_REMOTE_DIST_MODE) {
8560 + s->remote_distribution_mode = session->remote_distribution_mode;
8562 + if (flag & LDP_SESSION_CFG_REMOTE_LOOP_DETECTION) {
8563 + s->remote_loop_detection = session->remote_loop_detection;
8565 + if (flag & LDP_SESSION_CFG_REMOTE_ADDR) {
8566 + s->remote_dest.addr.type = session->remote_dest.addr.type;
8567 + s->remote_dest.addr.u.ipv4 = session->remote_dest.addr.u.ipv4;
8569 + if (flag & LDP_SESSION_CFG_REMOTE_PORT) {
8570 + s->remote_dest.port = session->remote_dest.port;
8572 + if (flag & LDP_SESSION_CFG_LABEL_RESOURCE_STATE_LOCAL) {
8573 + s->no_label_resource_sent = session->no_label_resource_sent;
8575 + if (flag & LDP_SESSION_CFG_LABEL_RESOURCE_STATE_REMOTE) {
8576 + s->no_label_resource_recv = session->no_label_resource_recv;
8578 + if (flag & LDP_SESSION_CFG_ADJ_INDEX) {
8579 + ldp_adj *a = MPLS_LIST_HEAD(&session->adj_root);
8580 + s->adj_index = a ? a->index : 0;
8582 + if (flag & LDP_SESSION_CFG_MESG_TX) {
8583 + s->mesg_tx = session->mesg_tx;
8585 + if (flag & LDP_SESSION_CFG_MESG_RX) {
8586 + s->mesg_rx = session->mesg_rx;
8588 + if (flag & LDP_SESSION_CFG_LOCAL_NAME) {
8589 + if (mpls_socket_handle_verify(global->socket_handle,
8590 + session->socket) == MPLS_BOOL_TRUE) {
8591 + mpls_socket_get_local_name(global->socket_handle, session->socket,
8592 + &s->local_name);
8595 + if (flag & LDP_SESSION_CFG_REMOTE_NAME) {
8596 + if (mpls_socket_handle_verify(global->socket_handle,
8597 + session->socket) == MPLS_BOOL_TRUE) {
8598 + mpls_socket_get_remote_name(global->socket_handle, session->socket,
8599 + &s->remote_name);
8602 + retval = MPLS_SUCCESS;
8604 +ldp_cfg_session_get_end:
8605 + mpls_lock_release(global->global_lock); /* UNLOCK */
8607 + LDP_EXIT(global->user_data, "ldp_cfg_session_get");
8609 + return retval;
8612 +mpls_return_enum ldp_cfg_session_getnext(mpls_cfg_handle handle, ldp_session * s,
8613 + uint32_t flag)
8615 + ldp_global *g = (ldp_global *) handle;
8616 + ldp_session *ses = NULL;
8617 + mpls_return_enum r = MPLS_FAILURE;
8618 + mpls_bool done = MPLS_BOOL_FALSE;
8619 + int index;
8621 + LDP_ENTER(g->user_data, "ldp_cfg_session_getnext");
8623 + if (s->index == 0) {
8624 + index = 1;
8625 + } else {
8626 + index = s->index + 1;
8629 + mpls_lock_get(g->global_lock); /* LOCK */
8630 + while (done == MPLS_BOOL_FALSE) {
8631 + switch ((r = ldp_global_find_session_index(g, index, &ses))) {
8632 + case MPLS_SUCCESS:
8633 + case MPLS_END_OF_LIST:
8634 + done = MPLS_BOOL_TRUE;
8635 + break;
8636 + case MPLS_FAILURE:
8637 + break;
8638 + default:
8639 + MPLS_ASSERT(0);
8641 + index++;
8643 + mpls_lock_release(g->global_lock); /* UNLOCK */
8645 + if (r == MPLS_SUCCESS) {
8646 + s->index = ses->index;
8648 + LDP_EXIT(g->user_data, "ldp_cfg_session_getnext");
8649 + return ldp_cfg_session_get(g, s, flag);
8652 + LDP_EXIT(g->user_data, "ldp_cfg_session_getnext");
8654 + return r;
8657 +mpls_return_enum ldp_cfg_session_adj_getnext(mpls_cfg_handle handle,
8658 + ldp_session * s)
8660 + ldp_global *g = (ldp_global *) handle;
8661 + mpls_bool this_one = MPLS_BOOL_FALSE;
8662 + mpls_return_enum r = MPLS_FAILURE;
8663 + ldp_adj *adj_next = NULL;
8664 + ldp_adj *adj = NULL;
8665 + ldp_session *session = NULL;
8667 + LDP_ENTER(g->user_data, "ldp_cfg_session_adj_getnext");
8669 + /* if an adj_index of zero is sent, get the index of
8670 + * the first adj in the list
8671 + */
8672 + if (!s->adj_index) {
8673 + this_one = MPLS_BOOL_TRUE;
8676 + mpls_lock_get(g->global_lock); /* LOCK */
8678 + if (ldp_global_find_session_index(g, s->index, &session) == MPLS_SUCCESS) {
8679 + adj = MPLS_LIST_HEAD(&session->adj_root);
8680 + while (adj) {
8681 + if (this_one == MPLS_BOOL_TRUE) {
8682 + adj_next = adj;
8683 + break;
8686 + /* since the entities are sort in the list ... */
8687 + if (adj->index > s->adj_index) {
8688 + break;
8689 + } else if (adj->index == s->adj_index) {
8690 + this_one = MPLS_BOOL_TRUE;
8692 + adj = MPLS_LIST_NEXT(&session->adj_root, adj, _session);
8695 + mpls_lock_release(g->global_lock); /* UNLOCK */
8697 + if (adj_next) {
8698 + s->adj_index = adj_next->index;
8699 + r = MPLS_SUCCESS;
8702 + LDP_EXIT(g->user_data, "ldp_cfg_session_adj_getnext");
8703 + return r;
8706 +mpls_return_enum ldp_cfg_session_raddr_get(mpls_cfg_handle handle,
8707 + ldp_session * s, ldp_addr * a, uint32_t flag)
8709 + ldp_global *global = (ldp_global *) handle;
8710 + ldp_session *session = NULL;
8711 + ldp_addr *addr = NULL;
8712 + mpls_return_enum retval = MPLS_FAILURE;
8714 + MPLS_ASSERT(global !=NULL && s != NULL && a != NULL);
8716 + LDP_ENTER(global->user_data, "ldp_cfg_session_raddr_get");
8718 + mpls_lock_get(global->global_lock); /* LOCK */
8720 + if (ldp_global_find_session_index(global, s->index, &session) != MPLS_SUCCESS)
8721 + goto ldp_cfg_session_raddr_get_end;
8723 + if (ldp_session_find_raddr_index(session, a->index, &addr) != MPLS_SUCCESS)
8724 + goto ldp_cfg_session_raddr_get_end;
8726 + if (flag & LDP_SESSION_RADDR_CFG_ADDR) {
8727 + memcpy(&a->address,&addr->address,sizeof(struct mpls_inet_addr));
8729 + if (flag & LDP_SESSION_RADDR_CFG_INDEX) {
8730 + a->index = addr->index;
8732 + retval = MPLS_SUCCESS;
8734 +ldp_cfg_session_raddr_get_end:
8735 + mpls_lock_release(global->global_lock); /* UNLOCK */
8737 + LDP_EXIT(global->user_data, "ldp_cfg_session_raddr_get");
8739 + return retval;
8742 +mpls_return_enum ldp_cfg_session_raddr_getnext(mpls_cfg_handle handle,
8743 + ldp_session * s, ldp_addr * a, uint32_t flag)
8745 + ldp_global *g = (ldp_global *) handle;
8746 + ldp_addr *addr = NULL;
8747 + mpls_return_enum r = MPLS_FAILURE;
8748 + mpls_bool done = MPLS_BOOL_FALSE;
8749 + ldp_session *sp = NULL;
8750 + int index;
8752 + LDP_ENTER(g->user_data, "ldp_cfg_session_raddr_getnext");
8754 + if (a->index == 0) {
8755 + index = 1;
8756 + } else {
8757 + index = a->index + 1;
8760 + r = ldp_global_find_session_index(g, s->index, &sp);
8761 + if (r != MPLS_SUCCESS) {
8762 + return r;
8765 + mpls_lock_get(g->global_lock); /* LOCK */
8766 + while (done == MPLS_BOOL_FALSE) {
8767 + switch ((r = ldp_session_find_raddr_index(sp, index, &addr))) {
8768 + case MPLS_SUCCESS:
8769 + case MPLS_END_OF_LIST:
8770 + done = MPLS_BOOL_TRUE;
8771 + break;
8772 + case MPLS_FAILURE:
8773 + break;
8774 + default:
8775 + MPLS_ASSERT(0);
8777 + index++;
8779 + mpls_lock_release(g->global_lock); /* UNLOCK */
8781 + if (r == MPLS_SUCCESS) {
8782 + a->index = addr->index;
8783 + r = ldp_cfg_session_raddr_get(handle, sp, a, flag);
8786 + LDP_EXIT(g->user_data, "ldp_cfg_session_getnext");
8787 + return r;
8790 +/******************* IN LABEL **********************/
8792 +mpls_return_enum ldp_cfg_inlabel_get(mpls_cfg_handle handle, ldp_inlabel * i,
8793 + uint32_t flag)
8795 + ldp_global *global = (ldp_global *) handle;
8796 + ldp_inlabel *inlabel = NULL;
8797 + mpls_return_enum retval = MPLS_FAILURE;
8799 + MPLS_ASSERT(global !=NULL && i != NULL);
8801 + LDP_ENTER(global->user_data, "ldp_cfg_inlabel_get");
8803 + mpls_lock_get(global->global_lock); /* LOCK */
8805 + if (ldp_global_find_inlabel_index(global, i->index, &inlabel) != MPLS_SUCCESS)
8806 + goto ldp_cfg_inlabel_get_end;
8808 + if (flag & LDP_INLABEL_CFG_LABELSPACE) {
8809 + i->info.labelspace = inlabel->info.labelspace;
8811 + if (flag & LDP_INLABEL_CFG_LABEL) {
8812 + memcpy(&i->info.label, &inlabel->info.label, sizeof(mpls_label_struct));
8814 + if (flag & LDP_INLABEL_CFG_OUTLABEL_INDEX) {
8815 + i->outlabel_index = (inlabel->outlabel) ? (inlabel->outlabel->index) : 0;
8818 + retval = MPLS_SUCCESS;
8820 +ldp_cfg_inlabel_get_end:
8821 + mpls_lock_release(global->global_lock); /* UNLOCK */
8823 + LDP_EXIT(global->user_data, "ldp_cfg_inlabel_get");
8825 + return retval;
8828 +mpls_return_enum ldp_cfg_inlabel_getnext(mpls_cfg_handle handle, ldp_inlabel * i,
8829 + uint32_t flag)
8831 + ldp_global *g = (ldp_global *) handle;
8832 + ldp_inlabel *inlabel = NULL;
8833 + mpls_return_enum r = MPLS_FAILURE;
8834 + mpls_bool done = MPLS_BOOL_FALSE;
8835 + int index;
8837 + LDP_ENTER(g->user_data, "ldp_cfg_inlabel_getnext");
8839 + if (i->index == 0) {
8840 + index = 1;
8841 + } else {
8842 + index = i->index + 1;
8845 + mpls_lock_get(g->global_lock); /* LOCK */
8846 + while (done == MPLS_BOOL_FALSE) {
8847 + switch ((r = ldp_global_find_inlabel_index(g, index, &inlabel))) {
8848 + case MPLS_SUCCESS:
8849 + case MPLS_END_OF_LIST:
8850 + done = MPLS_BOOL_TRUE;
8851 + break;
8852 + case MPLS_FAILURE:
8853 + break;
8854 + default:
8855 + MPLS_ASSERT(0);
8857 + index++;
8859 + mpls_lock_release(g->global_lock); /* UNLOCK */
8861 + if (r == MPLS_SUCCESS) {
8862 + i->index = inlabel->index;
8864 + LDP_EXIT(g->user_data, "ldp_cfg_inlabel_getnext");
8865 + return ldp_cfg_inlabel_get(g, i, flag);
8868 + LDP_EXIT(g->user_data, "ldp_cfg_inlabel_getnext");
8870 + return r;
8873 +/******************* OUT LABEL **********************/
8875 +mpls_return_enum ldp_cfg_outlabel_get(mpls_cfg_handle handle, ldp_outlabel * o,
8876 + uint32_t flag)
8878 + ldp_global *global = (ldp_global *) handle;
8879 + ldp_outlabel *outlabel = NULL;
8880 + mpls_return_enum retval = MPLS_FAILURE;
8882 + MPLS_ASSERT(global !=NULL && o != NULL);
8884 + LDP_ENTER(global->user_data, "ldp_cfg_outlabel_get");
8886 + mpls_lock_get(global->global_lock); /* LOCK */
8888 + if (ldp_global_find_outlabel_index(global, o->index,
8889 + &outlabel) != MPLS_SUCCESS) goto ldp_cfg_outlabel_get_end;
8891 + if (flag & LDP_OUTLABEL_CFG_NH_INDEX) {
8892 + if (outlabel->nh) {
8893 + o->nh_index = outlabel->nh->index;
8894 + } else {
8895 + o->nh_index = 0;
8898 + if (flag & LDP_OUTLABEL_CFG_SESSION_INDEX) {
8899 + o->session_index = (outlabel->session) ? (outlabel->session->index) : 0;
8901 + if (flag & LDP_OUTLABEL_CFG_LABEL) {
8902 + memcpy(&o->info.label, &outlabel->info.label, sizeof(mpls_label_struct));
8904 + if (flag & LDP_OUTLABEL_CFG_MERGE_COUNT) {
8905 + o->merge_count = outlabel->merge_count;
8908 + retval = MPLS_SUCCESS;
8910 +ldp_cfg_outlabel_get_end:
8911 + mpls_lock_release(global->global_lock); /* UNLOCK */
8913 + LDP_EXIT(global->user_data, "ldp_cfg_outlabel_get");
8915 + return retval;
8918 +mpls_return_enum ldp_cfg_outlabel_getnext(mpls_cfg_handle handle,
8919 + ldp_outlabel * o, uint32_t flag)
8921 + ldp_global *g = (ldp_global *) handle;
8922 + ldp_outlabel *outlabel = NULL;
8923 + mpls_return_enum r = MPLS_FAILURE;
8924 + mpls_bool done = MPLS_BOOL_FALSE;
8925 + int index;
8927 + LDP_ENTER(g->user_data, "ldp_cfg_outlabel_getnext");
8929 + if (o->index == 0) {
8930 + index = 1;
8931 + } else {
8932 + index = o->index + 1;
8935 + mpls_lock_get(g->global_lock); /* LOCK */
8936 + while (done == MPLS_BOOL_FALSE) {
8937 + switch ((r = ldp_global_find_outlabel_index(g, index, &outlabel))) {
8938 + case MPLS_SUCCESS:
8939 + case MPLS_END_OF_LIST:
8940 + done = MPLS_BOOL_TRUE;
8941 + break;
8942 + case MPLS_FAILURE:
8943 + break;
8944 + default:
8945 + MPLS_ASSERT(0);
8947 + index++;
8949 + mpls_lock_release(g->global_lock); /* UNLOCK */
8951 + if (r == MPLS_SUCCESS) {
8952 + o->index = outlabel->index;
8954 + LDP_EXIT(g->user_data, "ldp_cfg_outlabel_getnext");
8955 + return ldp_cfg_outlabel_get(g, o, flag);
8958 + LDP_EXIT(g->user_data, "ldp_cfg_outlabel_getnext");
8960 + return r;
8963 +/******************* TUNNEL **********************/
8965 +mpls_return_enum ldp_cfg_tunnel_set(mpls_cfg_handle handle, ldp_tunnel * t,
8966 + uint32_t flag)
8968 + ldp_global *global = (ldp_global *) handle;
8969 + mpls_return_enum retval = MPLS_FAILURE;
8970 + ldp_tunnel *tunnel = NULL;
8972 + MPLS_ASSERT(global !=NULL);
8974 + LDP_ENTER(global->user_data, "ldp_cfg_tunnel_set");
8976 + mpls_lock_get(global->global_lock); /* LOCK */
8978 + if (flag & LDP_CFG_ADD) {
8979 + if (!(tunnel = ldp_tunnel_create())) {
8980 + goto ldp_cfg_tunnel_set_end;
8982 + _ldp_global_add_tunnel(global, tunnel);
8984 + t->index = tunnel->index;
8985 + } else {
8986 + ldp_global_find_tunnel_index(global, t->index, &tunnel);
8989 + if (!tunnel) {
8990 + LDP_PRINT(global->user_data,
8992 + "ldp_cfg_tunnel_set:could not create tunnel\n");
8993 + goto ldp_cfg_tunnel_set_end;
8996 + if ((ldp_tunnel_is_active(tunnel) == MPLS_BOOL_TRUE) &&
8997 + (flag & LDP_TUNNEL_CFG_WHEN_DOWN)) {
8998 + LDP_PRINT(global->user_data, "ldp_cfg_tunnel_set: tunnel is active\n");
9000 + goto ldp_cfg_tunnel_set_end;
9003 + if (flag & LDP_CFG_DEL) {
9004 + if (tunnel->outlabel)
9005 + ldp_tunnel_del_outlabel(global, tunnel);
9006 + if (tunnel->resource)
9007 + ldp_tunnel_del_resource(tunnel);
9008 + if (tunnel->hop_list)
9009 + ldp_tunnel_del_hop_list(tunnel);
9010 + _ldp_global_del_tunnel(global, tunnel);
9012 + retval = MPLS_SUCCESS;
9013 + goto ldp_cfg_tunnel_set_end;
9016 + if (flag & LDP_TUNNEL_CFG_INGRESS) {
9017 + memcpy(&tunnel->ingress_lsrid, &t->ingress_lsrid, sizeof(ldp_addr));
9019 + if (flag & LDP_TUNNEL_CFG_EGRESS) {
9020 + memcpy(&tunnel->egress_lsrid, &t->egress_lsrid, sizeof(ldp_addr));
9022 + if (flag & LDP_TUNNEL_CFG_NAME) {
9023 + memcpy(&tunnel->name, &t->name, MPLS_MAX_IF_NAME);
9025 + if (flag & LDP_TUNNEL_CFG_IS_IF) {
9026 + tunnel->is_interface = t->is_interface;
9028 + if (flag & LDP_TUNNEL_CFG_OUTLABEL) {
9029 + ldp_outlabel *outlabel = NULL;
9031 + if (t->outlabel_index) {
9032 + ldp_global_find_outlabel_index(global, t->outlabel_index, &outlabel);
9034 + if (!outlabel) {
9035 + goto ldp_cfg_tunnel_set_end;
9037 + ldp_tunnel_add_outlabel(tunnel, outlabel);
9038 + } else {
9039 + ldp_tunnel_del_outlabel(global, tunnel);
9042 + if (flag & LDP_TUNNEL_CFG_SETUP_PRIO) {
9043 + tunnel->setup_prio = t->setup_prio;
9045 + if (flag & LDP_TUNNEL_CFG_HOLD_PRIO) {
9046 + tunnel->hold_prio = t->hold_prio;
9048 + if (flag & LDP_TUNNEL_CFG_INSTANCE_PRIO) {
9049 + tunnel->instance_prio = t->instance_prio;
9051 + if (flag & LDP_TUNNEL_CFG_LOCAL_PROTECT) {
9052 + tunnel->local_protect = t->local_protect;
9054 + if (flag & LDP_TUNNEL_CFG_RESOURCE_INDEX) {
9055 + ldp_resource *resource = NULL;
9057 + if (t->resource_index) {
9058 + ldp_global_find_resource_index(global, t->resource_index, &resource);
9060 + if (!resource) {
9061 + goto ldp_cfg_tunnel_set_end;
9063 + ldp_tunnel_add_resource(tunnel, resource);
9064 + } else {
9065 + ldp_tunnel_del_resource(tunnel);
9068 + if (flag & LDP_TUNNEL_CFG_HOP_LIST_INDEX) {
9069 + ldp_hop_list *hop_list = NULL;
9071 + if (t->hop_list_index) {
9072 + ldp_global_find_hop_list_index(global, t->hop_list_index, &hop_list);
9074 + if (!hop_list) {
9075 + goto ldp_cfg_tunnel_set_end;
9077 + ldp_tunnel_add_hop_list(tunnel, hop_list);
9078 + } else {
9079 + ldp_tunnel_del_hop_list(tunnel);
9082 + if (flag & LDP_TUNNEL_CFG_FEC) {
9083 + memcpy(&tunnel->fec, &t->fec, sizeof(ldp_fec));
9085 + if (flag & LDP_TUNNEL_CFG_ADMIN_STATE) {
9086 + if (ldp_tunnel_is_active(tunnel) == MPLS_BOOL_TRUE) {
9087 + if (t->admin_state == MPLS_ADMIN_DISABLE) {
9088 + if (ldp_tunnel_shutdown(global, tunnel, 0) == MPLS_FAILURE) {
9089 + goto ldp_cfg_tunnel_set_end;
9092 + } else {
9093 + if (t->admin_state == MPLS_ADMIN_ENABLE) {
9094 + if (ldp_tunnel_is_ready(tunnel) == MPLS_BOOL_TRUE) {
9095 + if (ldp_tunnel_startup(global, tunnel) == MPLS_FAILURE) {
9096 + goto ldp_cfg_tunnel_set_end;
9098 + } else {
9099 + LDP_PRINT(global->user_data,
9101 + "ldp_cfg_tunnel_set: tunnel not ready\n");
9102 + goto ldp_cfg_tunnel_set_end;
9107 + retval = MPLS_SUCCESS;
9109 +ldp_cfg_tunnel_set_end:
9111 + mpls_lock_release(global->global_lock); /* UNLOCK */
9113 + LDP_EXIT(global->user_data, "ldp_cfg_tunnel_set");
9115 + return retval;
9118 +mpls_return_enum ldp_cfg_tunnel_test(mpls_cfg_handle handle, ldp_tunnel * t,
9119 + uint32_t flag)
9121 + ldp_global *global = (ldp_global *) handle;
9122 + mpls_return_enum retval = MPLS_FAILURE;
9123 + ldp_tunnel *tunnel = NULL;
9125 + MPLS_ASSERT(global !=NULL);
9127 + LDP_ENTER(global->user_data, "ldp_cfg_tunnel_test");
9129 + mpls_lock_get(global->global_lock); /* LOCK */
9131 + if (flag & LDP_CFG_ADD) {
9132 + retval = MPLS_SUCCESS;
9133 + goto ldp_cfg_tunnel_test_end;
9136 + ldp_global_find_tunnel_index(global, t->index, &tunnel);
9138 + if (!tunnel) {
9139 + goto ldp_cfg_tunnel_test_end;
9142 + if (flag & LDP_TUNNEL_CFG_RESOURCE_INDEX) {
9143 + ldp_resource *resource = NULL;
9145 + if (t->resource_index) {
9146 + ldp_global_find_resource_index(global, t->resource_index, &resource);
9148 + if (!resource) {
9149 + goto ldp_cfg_tunnel_test_end;
9153 + if (flag & LDP_TUNNEL_CFG_HOP_LIST_INDEX) {
9154 + ldp_hop_list *hop_list = NULL;
9156 + if (t->hop_list_index) {
9157 + ldp_global_find_hop_list_index(global, t->hop_list_index, &hop_list);
9159 + if (!hop_list) {
9160 + goto ldp_cfg_tunnel_test_end;
9164 + if (flag & LDP_TUNNEL_CFG_OUTLABEL) {
9165 + ldp_outlabel *outlabel = NULL;
9167 + if (t->outlabel_index) {
9168 + ldp_global_find_outlabel_index(global, t->outlabel_index, &outlabel);
9170 + if (!outlabel) {
9171 + goto ldp_cfg_tunnel_test_end;
9175 + if ((flag & LDP_TUNNEL_CFG_ADMIN_STATE) &&
9176 + (ldp_tunnel_is_active(tunnel) == MPLS_BOOL_FALSE) &&
9177 + (t->admin_state == MPLS_ADMIN_ENABLE) && (ldp_tunnel_is_ready(tunnel) != MPLS_BOOL_TRUE)) {
9178 + goto ldp_cfg_tunnel_test_end;
9180 + retval = MPLS_SUCCESS;
9182 +ldp_cfg_tunnel_test_end:
9184 + mpls_lock_release(global->global_lock); /* UNLOCK */
9186 + LDP_EXIT(global->user_data, "ldp_cfg_tunnel_test");
9188 + return retval;
9191 +mpls_return_enum ldp_cfg_tunnel_get(mpls_cfg_handle handle, ldp_tunnel * t,
9192 + uint32_t flag)
9194 + ldp_global *global = (ldp_global *) handle;
9195 + mpls_return_enum retval = MPLS_FAILURE;
9196 + ldp_tunnel *tunnel = NULL;
9198 + MPLS_ASSERT(global !=NULL);
9200 + LDP_ENTER(global->user_data, "ldp_cfg_tunnel_get");
9202 + mpls_lock_get(global->global_lock); /* LOCK */
9204 + ldp_global_find_tunnel_index(global, t->index, &tunnel);
9206 + if (!tunnel) {
9207 + goto ldp_cfg_tunnel_get_end;
9209 + if (flag & LDP_TUNNEL_CFG_INGRESS) {
9210 + memcpy(&t->ingress_lsrid, &tunnel->ingress_lsrid, sizeof(ldp_addr));
9212 + if (flag & LDP_TUNNEL_CFG_EGRESS) {
9213 + memcpy(&t->egress_lsrid, &tunnel->egress_lsrid, sizeof(ldp_addr));
9215 + if (flag & LDP_TUNNEL_CFG_NAME) {
9216 + memcpy(&t->name, &tunnel->name, MPLS_MAX_IF_NAME);
9218 + if (flag & LDP_TUNNEL_CFG_IS_IF) {
9219 + t->is_interface = tunnel->is_interface;
9221 + if (flag & LDP_TUNNEL_CFG_OUTLABEL) {
9222 + if (tunnel->outlabel) {
9223 + t->outlabel_index = tunnel->outlabel->index;
9224 + } else {
9225 + t->outlabel_index = 0;
9228 + if (flag & LDP_TUNNEL_CFG_SETUP_PRIO) {
9229 + t->setup_prio = tunnel->setup_prio;
9231 + if (flag & LDP_TUNNEL_CFG_HOLD_PRIO) {
9232 + t->hold_prio = tunnel->hold_prio;
9234 + if (flag & LDP_TUNNEL_CFG_INSTANCE_PRIO) {
9235 + tunnel->instance_prio = t->instance_prio;
9237 + if (flag & LDP_TUNNEL_CFG_LOCAL_PROTECT) {
9238 + tunnel->local_protect = t->local_protect;
9240 + if (flag & LDP_TUNNEL_CFG_RESOURCE_INDEX) {
9241 + if (tunnel->resource) {
9242 + t->resource_index = tunnel->resource->index;
9243 + } else {
9244 + t->resource_index = 0;
9247 + if (flag & LDP_TUNNEL_CFG_HOP_LIST_INDEX) {
9248 + if (tunnel->hop_list) {
9249 + t->hop_list_index = tunnel->hop_list->index;
9250 + } else {
9251 + t->hop_list_index = 0;
9254 + if (flag & LDP_TUNNEL_CFG_FEC) {
9255 + memcpy(&t->fec, &tunnel->fec, sizeof(ldp_fec));
9257 + if (flag & LDP_TUNNEL_CFG_ADMIN_STATE) {
9258 + t->admin_state = tunnel->admin_state;
9260 + retval = MPLS_SUCCESS;
9262 +ldp_cfg_tunnel_get_end:
9264 + mpls_lock_release(global->global_lock); /* UNLOCK */
9266 + LDP_EXIT(global->user_data, "ldp_cfg_tunnel_get");
9268 + return retval;
9271 +/******************* RESOURCE **********************/
9273 +mpls_return_enum ldp_cfg_resource_set(mpls_cfg_handle handle, ldp_resource * r,
9274 + uint32_t flag)
9276 + ldp_global *global = (ldp_global *) handle;
9277 + mpls_return_enum retval = MPLS_FAILURE;
9278 + ldp_resource *resource = NULL;
9280 + MPLS_ASSERT(global !=NULL);
9282 + LDP_ENTER(global->user_data, "ldp_cfg_resource_set");
9284 + mpls_lock_get(global->global_lock); /* LOCK */
9286 + if (flag & LDP_CFG_ADD) {
9287 + resource = ldp_resource_create();
9288 + _ldp_global_add_resource(global, resource);
9290 + r->index = resource->index;
9291 + } else {
9292 + ldp_global_find_resource_index(global, r->index, &resource);
9295 + if (!resource) {
9296 + goto ldp_cfg_resource_set_end;
9299 + if (flag & LDP_RESOURCE_CFG_MAXBPS) {
9300 + resource->max_rate = r->max_rate;
9302 + if (flag & LDP_RESOURCE_CFG_MEANBPS) {
9303 + resource->mean_rate = r->mean_rate;
9305 + if (flag & LDP_RESOURCE_CFG_BURSTSIZE) {
9306 + resource->burst_size = r->burst_size;
9308 + retval = MPLS_SUCCESS;
9310 +ldp_cfg_resource_set_end:
9312 + mpls_lock_release(global->global_lock); /* UNLOCK */
9314 + LDP_EXIT(global->user_data, "ldp_cfg_resource_set");
9316 + return retval;
9319 +mpls_return_enum ldp_cfg_resource_test(mpls_cfg_handle handle, ldp_resource * r,
9320 + uint32_t flag)
9322 + ldp_global *global = (ldp_global *) handle;
9323 + mpls_return_enum retval = MPLS_FAILURE;
9324 + ldp_resource *resource = NULL;
9326 + MPLS_ASSERT(global !=NULL);
9328 + LDP_ENTER(global->user_data, "ldp_cfg_resource_test");
9330 + mpls_lock_get(global->global_lock); /* LOCK */
9332 + if (flag & LDP_CFG_ADD) {
9333 + retval = MPLS_SUCCESS;
9334 + goto ldp_cfg_resource_test_end;
9337 + ldp_global_find_resource_index(global, r->index, &resource);
9339 + if (!resource) {
9340 + goto ldp_cfg_resource_test_end;
9343 + if (ldp_resource_in_use(resource) == MPLS_BOOL_TRUE) {
9344 + goto ldp_cfg_resource_test_end;
9346 + retval = MPLS_SUCCESS;
9348 +ldp_cfg_resource_test_end:
9350 + mpls_lock_release(global->global_lock); /* UNLOCK */
9352 + LDP_EXIT(global->user_data, "ldp_cfg_resource_test");
9354 + return retval;
9357 +mpls_return_enum ldp_cfg_resource_get(mpls_cfg_handle handle, ldp_resource * r,
9358 + uint32_t flag)
9360 + ldp_global *global = (ldp_global *) handle;
9361 + mpls_return_enum retval = MPLS_FAILURE;
9362 + ldp_resource *resource = NULL;
9364 + MPLS_ASSERT(global !=NULL);
9366 + LDP_ENTER(global->user_data, "ldp_cfg_resource_get");
9368 + mpls_lock_get(global->global_lock); /* LOCK */
9370 + ldp_global_find_resource_index(global, r->index, &resource);
9372 + if (!resource) {
9373 + goto ldp_cfg_resource_get_end;
9376 + if (flag & LDP_RESOURCE_CFG_MAXBPS) {
9377 + r->max_rate = resource->max_rate;
9379 + if (flag & LDP_RESOURCE_CFG_MEANBPS) {
9380 + r->mean_rate = resource->mean_rate;
9382 + if (flag & LDP_RESOURCE_CFG_BURSTSIZE) {
9383 + r->burst_size = resource->burst_size;
9385 + retval = MPLS_SUCCESS;
9387 +ldp_cfg_resource_get_end:
9389 + mpls_lock_release(global->global_lock); /* UNLOCK */
9391 + LDP_EXIT(global->user_data, "ldp_cfg_resource_get");
9393 + return retval;
9396 +/******************* HOP **********************/
9398 +mpls_return_enum ldp_cfg_hop_set(mpls_cfg_handle handle, ldp_hop * h,
9399 + uint32_t flag)
9401 + ldp_global *global = (ldp_global *) handle;
9402 + mpls_return_enum retval = MPLS_FAILURE;
9403 + ldp_hop_list *hop_list = NULL;
9404 + ldp_hop *hop = NULL;
9406 + MPLS_ASSERT(global !=NULL);
9408 + LDP_ENTER(global->user_data, "ldp_cfg_hop_set");
9410 + if (!h->hop_list_index && !h->index) {
9411 + return retval;
9414 + mpls_lock_get(global->global_lock); /* LOCK */
9416 + ldp_global_find_hop_list_index(global, h->hop_list_index, &hop_list);
9418 + if (!hop_list) {
9419 + if (flag & LDP_CFG_ADD) {
9420 + if (!(hop_list = ldp_hop_list_create())) {
9421 + goto ldp_cfg_hop_set_end;
9423 + _ldp_global_add_hop_list(global, hop_list);
9425 + h->hop_list_index = hop_list->index;
9426 + } else {
9427 + goto ldp_cfg_hop_set_end;
9431 + ldp_hop_list_find_hop_index(hop_list, h->index, &hop);
9432 + if (!hop) {
9433 + if (h->index && (flag & LDP_CFG_ADD)) {
9434 + if (!(hop = ldp_hop_create())) {
9435 + goto ldp_cfg_hop_set_end;
9437 + hop->index = h->index;
9438 + ldp_hop_list_add_hop(hop_list, hop);
9439 + } else {
9440 + goto ldp_cfg_hop_set_end;
9444 + if (flag & LDP_HOP_CFG_PATH_OPTION) {
9445 + hop->path_option = h->path_option;
9447 + if (flag & LDP_HOP_CFG_ADDR) {
9448 + memcpy(&hop->addr, &h->addr, sizeof(ldp_addr));
9450 + if (flag & LDP_HOP_CFG_TYPE) {
9451 + hop->type = h->type;
9453 + retval = MPLS_SUCCESS;
9455 +ldp_cfg_hop_set_end:
9457 + mpls_lock_release(global->global_lock); /* UNLOCK */
9459 + LDP_EXIT(global->user_data, "ldp_cfg_hop_set");
9461 + return retval;
9464 +mpls_return_enum ldp_cfg_hop_test(mpls_cfg_handle handle, ldp_hop * h,
9465 + uint32_t flag)
9467 + ldp_global *global = (ldp_global *) handle;
9468 + mpls_return_enum retval = MPLS_FAILURE;
9469 + ldp_hop_list *hop_list = NULL;
9470 + ldp_hop *hop = NULL;
9472 + MPLS_ASSERT(global !=NULL);
9474 + LDP_ENTER(global->user_data, "ldp_cfg_hop_test");
9476 + mpls_lock_get(global->global_lock); /* LOCK */
9478 + if (flag & LDP_CFG_ADD) {
9479 + retval = MPLS_SUCCESS;
9480 + goto ldp_cfg_hop_test_end;
9483 + ldp_global_find_hop_list_index(global, h->hop_list_index, &hop_list);
9485 + if (!hop_list) {
9486 + goto ldp_cfg_hop_test_end;
9489 + ldp_hop_list_find_hop_index(hop_list, h->index, &hop);
9490 + if (!hop) {
9491 + goto ldp_cfg_hop_test_end;
9494 + if (ldp_hop_in_use(hop) == MPLS_BOOL_TRUE) {
9495 + goto ldp_cfg_hop_test_end;
9497 + retval = MPLS_SUCCESS;
9499 +ldp_cfg_hop_test_end:
9501 + mpls_lock_release(global->global_lock); /* UNLOCK */
9503 + LDP_EXIT(global->user_data, "ldp_cfg_hop_test");
9505 + return retval;
9508 +mpls_return_enum ldp_cfg_hop_get(mpls_cfg_handle handle, ldp_hop * h,
9509 + uint32_t flag)
9511 + ldp_global *global = (ldp_global *) handle;
9512 + mpls_return_enum retval = MPLS_FAILURE;
9513 + ldp_hop_list *hop_list = NULL;
9514 + ldp_hop *hop = NULL;
9516 + MPLS_ASSERT(global !=NULL);
9518 + LDP_ENTER(global->user_data, "ldp_cfg_hop_get");
9520 + mpls_lock_get(global->global_lock); /* LOCK */
9522 + ldp_global_find_hop_list_index(global, h->hop_list_index, &hop_list);
9524 + if (!hop_list) {
9525 + goto ldp_cfg_hop_get_end;
9528 + ldp_hop_list_find_hop_index(hop_list, h->index, &hop);
9529 + if (!hop) {
9530 + goto ldp_cfg_hop_get_end;
9533 + if (flag & LDP_HOP_CFG_PATH_OPTION) {
9534 + h->path_option = hop->path_option;
9536 + if (flag & LDP_HOP_CFG_ADDR) {
9537 + memcpy(&h->addr, &hop->addr, sizeof(ldp_addr));
9539 + if (flag & LDP_HOP_CFG_TYPE) {
9540 + h->type = hop->type;
9542 + retval = MPLS_SUCCESS;
9544 +ldp_cfg_hop_get_end:
9546 + mpls_lock_release(global->global_lock); /* UNLOCK */
9548 + LDP_EXIT(global->user_data, "ldp_cfg_hop_get");
9550 + return retval;
9552 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_cfg.h quagga-mpls/ldpd/ldp_cfg.h
9553 --- quagga/ldpd/ldp_cfg.h 1969-12-31 18:00:00.000000000 -0600
9554 +++ quagga-mpls/ldpd/ldp_cfg.h 2006-11-21 20:41:04.000000000 -0600
9555 @@ -0,0 +1,341 @@
9558 + * Copyright (C) James R. Leu 2000
9559 + * jleu@mindspring.com
9561 + * This software is covered under the LGPL, for more
9562 + * info check out http://www.gnu.org/copyleft/lgpl.html
9563 + */
9565 +#ifndef _LDP_CFG_H_
9566 +#define _LDP_CFG_H_
9568 +#include "ldp_struct.h"
9569 +#include "ldp_entity.h"
9570 +#include "ldp_session.h"
9572 +#define LDP_CFG_ADD 0x00000001
9573 +#define LDP_CFG_DEL 0x10000000
9575 +#define LDP_GLOBAL_CFG_ADMIN_STATE 0x00000002
9576 +#define LDP_GLOBAL_CFG_CONTROL_MODE 0x00000004
9577 +#define LDP_GLOBAL_CFG_RETENTION_MODE 0x00000008
9578 +#define LDP_GLOBAL_CFG_REPAIR_MODE 0x00000010
9579 +#define LDP_GLOBAL_CFG_PROPOGATE_RELEASE 0x00000020
9580 +#define LDP_GLOBAL_CFG_LABEL_MERGE 0x00000040
9581 +#define LDP_GLOBAL_CFG_LOOP_DETECTION_MODE 0x00000080
9582 +#define LDP_GLOBAL_CFG_TTLLESS_DOMAIN 0x00000100
9583 +#define LDP_GLOBAL_CFG_LOCAL_TCP_PORT 0x00000200
9584 +#define LDP_GLOBAL_CFG_LOCAL_UDP_PORT 0x00000400
9585 +#define LDP_GLOBAL_CFG_LSR_IDENTIFIER 0x00000800
9586 +#define LDP_GLOBAL_CFG_TRANS_ADDR 0x00001000
9587 +#define LDP_GLOBAL_CFG_KEEPALIVE_TIMER 0x00002000
9588 +#define LDP_GLOBAL_CFG_KEEPALIVE_INTERVAL 0x00004000
9589 +#define LDP_GLOBAL_CFG_HELLOTIME_TIMER 0x00008000
9590 +#define LDP_GLOBAL_CFG_HELLOTIME_INTERVAL 0x00010000
9591 +#define LDP_GLOBAL_CFG_LSR_HANDLE 0x00020000
9593 +#define LDP_GLOBAL_CFG_WHEN_DOWN (LDP_GLOBAL_CFG_LOCAL_TCP_PORT|\
9594 + LDP_GLOBAL_CFG_LOCAL_UDP_PORT|\
9595 + LDP_GLOBAL_CFG_LSR_IDENTIFIER)
9597 +#define LDP_ENTITY_CFG_TRANS_ADDR 0x00000002
9598 +#define LDP_ENTITY_CFG_PROTO_VER 0x00000004
9599 +#define LDP_ENTITY_CFG_REMOTE_TCP 0x00000008
9600 +#define LDP_ENTITY_CFG_REMOTE_UDP 0x00000010
9601 +#define LDP_ENTITY_CFG_MAX_PDU 0x00000020
9602 +#define LDP_ENTITY_CFG_KEEPALIVE_TIMER 0x00000040
9603 +#define LDP_ENTITY_CFG_KEEPALIVE_INTERVAL 0x00000080
9604 +#define LDP_ENTITY_CFG_HELLOTIME_TIMER 0x00000100
9605 +#define LDP_ENTITY_CFG_HELLOTIME_INTERVAL 0x00000200
9606 +#define LDP_ENTITY_CFG_SESSION_SETUP_COUNT 0x00000400
9607 +#define LDP_ENTITY_CFG_SESSION_BACKOFF_TIMER 0x00000800
9608 +#define LDP_ENTITY_CFG_DISTRIBUTION_MODE 0x00001000
9609 +#define LDP_ENTITY_CFG_PATHVECTOR_LIMIT 0x00002000
9610 +#define LDP_ENTITY_CFG_HOPCOUNT_LIMIT 0x00004000
9611 +#define LDP_ENTITY_CFG_REQUEST_TIMER 0x00008000
9612 +#define LDP_ENTITY_CFG_REQUEST_COUNT 0x00010000
9613 +#define LDP_ENTITY_CFG_ADMIN_STATE 0x00020000
9614 +#define LDP_ENTITY_CFG_ADJ_COUNT 0x00040000
9615 +#define LDP_ENTITY_CFG_TYPE 0x00080000
9616 +#define LDP_ENTITY_CFG_SUB_INDEX 0x00100000
9617 +#define LDP_ENTITY_CFG_INHERIT_FLAG 0x00200000
9618 +#define LDP_ENTITY_CFG_MESG_TX 0x00400000
9619 +#define LDP_ENTITY_CFG_MESG_RX 0x00800000
9620 +#define LDP_ENTITY_CFG_ADJ_INDEX 0x01000000
9622 +#define LDP_ENTITY_CFG_WHEN_DOWN (LDP_CFG_DEL|\
9623 + LDP_ENTITY_CFG_TRANS_ADDR|\
9624 + LDP_ENTITY_CFG_PROTO_VER|\
9625 + LDP_ENTITY_CFG_REMOTE_TCP|\
9626 + LDP_ENTITY_CFG_REMOTE_UDP|\
9627 + LDP_ENTITY_CFG_DISTRIBUTION_MODE|\
9628 + LDP_ENTITY_CFG_TYPE|\
9629 + LDP_ENTITY_CFG_SUB_INDEX)
9631 +#define LDP_FEC_CFG_BY_INDEX 0x00000002
9632 +#define LDP_FEC_NEXTHOP_CFG_BY_INDEX 0x00000004
9634 +#define LDP_IF_CFG_LABEL_SPACE 0x00000002
9635 +#define LDP_IF_CFG_INDEX 0x00000004
9636 +#define LDP_IF_CFG_ENTITY_INDEX 0x00000008
9637 +#define LDP_IF_CFG_OPER_STATE 0x00000010
9638 +#define LDP_IF_CFG_BY_INDEX 0x00000080
9639 +#define LDP_IF_ADDR_CFG_BY_INDEX 0x00000100
9640 +#define LDP_IF_CFG_HANDLE 0x00000200
9642 +#define LDP_IF_CFG_WHEN_DOWN (LDP_CFG_DEL|\
9643 + LDP_IF_CFG_LABEL_SPACE|\
9644 + LDP_IF_CFG_INDEX|\
9645 + LDP_IF_CFG_ENTITY_INDEX|\
9646 + LDP_IF_CFG_OPER_STATE|\
9647 + LDP_IF_CFG_HANDLE)
9649 +#define LDP_PEER_CFG_LABEL_SPACE 0x00000002
9650 +#define LDP_PEER_CFG_DEST_ADDR 0x00000004
9651 +#define LDP_PEER_CFG_TARGET_ROLE 0x00000008
9652 +#define LDP_PEER_CFG_ENTITY_INDEX 0x00000010
9653 +#define LDP_PEER_CFG_OPER_STATE 0x00000020
9654 +#define LDP_PEER_CFG_PEER_NAME 0x00000040
9655 +#define LDP_PEER_CFG_LOCAL_SOURCE_ADDR 0x00000080
9657 +#define LDP_PEER_CFG_WHEN_DOWN (LDP_CFG_DEL|\
9658 + LDP_PEER_CFG_LABEL_SPACE|\
9659 + LDP_PEER_CFG_DEST_ADDR|\
9660 + LDP_PEER_CFG_TARGET_ROLE)
9662 +#define LDP_SESSION_CFG_INDEX 0x00000002
9663 +#define LDP_SESSION_CFG_STATE 0x00000004
9664 +#define LDP_SESSION_CFG_MAX_PDU 0x00000008
9665 +#define LDP_SESSION_CFG_KEEPALIVE 0x00000010
9666 +#define LDP_SESSION_CFG_PATH_LIMIT 0x00000020
9667 +#define LDP_SESSION_CFG_DIST_MODE 0x00000040
9668 +#define LDP_SESSION_CFG_LOOP_DETECTION 0x00000080
9669 +#define LDP_SESSION_CFG_REMOTE_MAX_PDU 0x00000100
9670 +#define LDP_SESSION_CFG_REMOTE_KEEPALIVE 0x00000200
9671 +#define LDP_SESSION_CFG_REMOTE_PATH_LIMIT 0x00000400
9672 +#define LDP_SESSION_CFG_REMOTE_DIST_MODE 0x00000800
9673 +#define LDP_SESSION_CFG_REMOTE_LOOP_DETECTION 0x00001000
9674 +#define LDP_SESSION_CFG_REMOTE_ADDR 0x00002000
9675 +#define LDP_SESSION_CFG_REMOTE_PORT 0x00004000
9676 +#define LDP_SESSION_CFG_LABEL_RESOURCE_STATE_LOCAL 0x00008000
9677 +#define LDP_SESSION_CFG_LABEL_RESOURCE_STATE_REMOTE 0x00010000
9678 +#define LDP_SESSION_CFG_ENTITY_INDEX 0x00020000
9679 +#define LDP_SESSION_CFG_ADJ_INDEX 0x00040000
9680 +#define LDP_SESSION_CFG_MESG_TX 0x00080000
9681 +#define LDP_SESSION_CFG_MESG_RX 0x00100000
9682 +#define LDP_SESSION_CFG_OPER_UP 0x00200000
9683 +#define LDP_SESSION_CFG_LOCAL_NAME 0x00400000
9684 +#define LDP_SESSION_CFG_REMOTE_NAME 0x00800000
9686 +#define LDP_SESSION_RADDR_CFG_ADDR 0x00000002
9687 +#define LDP_SESSION_RADDR_CFG_INDEX 0x00000004
9689 +#define LDP_ATTR_CFG_STATE 0x00000002
9690 +#define LDP_ATTR_CFG_FEC 0x00000004
9691 +#define LDP_ATTR_CFG_LABEL 0x00000008
9692 +#define LDP_ATTR_CFG_HOP_COUNT 0x00000010
9693 +#define LDP_ATTR_CFG_PATH 0x00000020
9694 +#define LDP_ATTR_CFG_SESSION_INDEX 0x00000040
9695 +#define LDP_ATTR_CFG_INLABEL_INDEX 0x00000080
9696 +#define LDP_ATTR_CFG_OUTLABEL_INDEX 0x00000100
9697 +#define LDP_ATTR_CFG_INGRESS 0x00000200
9699 +#define LDP_ADJ_CFG_REMOTE_TRADDR 0x00000002
9700 +#define LDP_ADJ_CFG_REMOTE_SRCADDR 0x00000004
9701 +#define LDP_ADJ_CFG_REMOTE_LSRADDR 0x00000008
9702 +#define LDP_ADJ_CFG_REMOTE_CSN 0x00000010
9703 +#define LDP_ADJ_CFG_REMOTE_LABELSPACE 0x00000020
9704 +#define LDP_ADJ_CFG_REMOTE_HELLOTIME 0x00000040
9705 +#define LDP_ADJ_CFG_ENTITY_INDEX 0x00000080
9706 +#define LDP_ADJ_CFG_REMOTE_SESSION_INDEX 0x00000100
9707 +#define LDP_ADJ_CFG_ROLE 0x00000200
9709 +#define LDP_INLABEL_CFG_LABELSPACE 0x00000002
9710 +#define LDP_INLABEL_CFG_LABEL 0x00000004
9711 +#define LDP_INLABEL_CFG_OUTLABEL_INDEX 0x00000008
9713 +#define LDP_OUTLABEL_CFG_NH_INDEX 0x00000002
9714 +#define LDP_OUTLABEL_CFG_SESSION_INDEX 0x00000004
9715 +#define LDP_OUTLABEL_CFG_LABEL 0x00000008
9716 +#define LDP_OUTLABEL_CFG_MERGE_COUNT 0x00000010
9718 +#define LDP_TUNNEL_CFG_INDEX 0x00000002
9719 +#define LDP_TUNNEL_CFG_INSTANCE 0x00000004
9720 +#define LDP_TUNNEL_CFG_INGRESS 0x00000008
9721 +#define LDP_TUNNEL_CFG_EGRESS 0x00000010
9722 +#define LDP_TUNNEL_CFG_NAME 0x00000020
9723 +#define LDP_TUNNEL_CFG_IS_IF 0x00000040
9724 +#define LDP_TUNNEL_CFG_OUTLABEL 0x00000080
9725 +#define LDP_TUNNEL_CFG_SETUP_PRIO 0x00000100
9726 +#define LDP_TUNNEL_CFG_HOLD_PRIO 0x00000200
9727 +#define LDP_TUNNEL_CFG_INSTANCE_PRIO 0x00000400
9728 +#define LDP_TUNNEL_CFG_LOCAL_PROTECT 0x00000800
9729 +#define LDP_TUNNEL_CFG_RESOURCE_INDEX 0x00001000
9730 +#define LDP_TUNNEL_CFG_HOP_LIST_INDEX 0x00002000
9731 +#define LDP_TUNNEL_CFG_ROLE 0x00004000
9732 +#define LDP_TUNNEL_CFG_ADMIN_STATE 0x00008000
9733 +#define LDP_TUNNEL_CFG_FEC 0x00010000
9735 +#define LDP_TUNNEL_CFG_WHEN_DOWN (LDP_CFG_DEL|\
9736 + LDP_TUNNEL_CFG_OUTLABEL|\
9737 + LDP_TUNNEL_CFG_RESOURCE_INDEX|\
9738 + LDP_TUNNEL_CFG_HOP_LIST_INDEX)
9740 +#define LDP_RESOURCE_CFG_INDEX 0x00000002
9741 +#define LDP_RESOURCE_CFG_MAXBPS 0x00000004
9742 +#define LDP_RESOURCE_CFG_MEANBPS 0x00000008
9743 +#define LDP_RESOURCE_CFG_BURSTSIZE 0x00000010
9745 +#define LDP_RESOURCE_CFG_WHEN_DOWN (LDP_CFG_DEL|\
9746 + LDP_RESOURCE_CFG_MAXBPS|\
9747 + LDP_RESOURCE_CFG_MEANBPS|\
9748 + LDP_RESOURCE_CFG_BURSTSIZE)
9750 +#define LDP_HOP_CFG_INDEX 0x00000002
9751 +#define LDP_HOP_CFG_LIST_INDEX 0x00000004
9752 +#define LDP_HOP_CFG_PATH_OPTION 0x00000008
9753 +#define LDP_HOP_CFG_ADDR 0x00000010
9754 +#define LDP_HOP_CFG_TYPE 0x00000020
9756 +#define LDP_HOP_CFG_WHEN_DOWN (LDP_CFG_DEL|\
9757 + LDP_HOP_CFG_INDEX|\
9758 + LDP_HOP_CFG_LIST_INDEX|\
9759 + LDP_HOP_CFG_ADDR|\
9760 + LDP_HOP_CFG_TYPE)
9762 +extern mpls_cfg_handle ldp_cfg_open(mpls_instance_handle data);
9763 +extern void ldp_cfg_close(mpls_cfg_handle handle);
9765 +extern mpls_return_enum ldp_cfg_global_get(mpls_cfg_handle handle,
9766 + ldp_global * g, uint32_t flag);
9767 +extern mpls_return_enum ldp_cfg_global_set(mpls_cfg_handle handle,
9768 + ldp_global * g, uint32_t flag);
9769 +extern void ldp_cfg_global_attr(mpls_cfg_handle handle);
9771 +extern mpls_return_enum ldp_cfg_entity_get(mpls_cfg_handle handle,
9772 + ldp_entity * e, uint32_t flag);
9773 +extern mpls_return_enum ldp_cfg_entity_getnext(mpls_cfg_handle handle,
9774 + ldp_entity * e, uint32_t flag);
9775 +extern mpls_return_enum ldp_cfg_entity_test(mpls_cfg_handle handle,
9776 + ldp_entity * e, uint32_t flag);
9777 +extern mpls_return_enum ldp_cfg_entity_set(mpls_cfg_handle handle,
9778 + ldp_entity * e, uint32_t flag);
9779 +extern mpls_return_enum ldp_cfg_entity_adj_getnext(mpls_cfg_handle handle,
9780 + ldp_entity * e);
9782 +extern mpls_return_enum ldp_cfg_attr_get(mpls_cfg_handle handle, ldp_attr * a,
9783 + uint32_t flag);
9784 +extern mpls_return_enum ldp_cfg_attr_getnext(mpls_cfg_handle handle,
9785 + ldp_attr * a, uint32_t flag);
9787 +extern mpls_return_enum ldp_cfg_peer_get(mpls_cfg_handle handle, ldp_peer * p,
9788 + uint32_t flag);
9789 +extern mpls_return_enum ldp_cfg_peer_getnext(mpls_cfg_handle handle,
9790 + ldp_peer * p, uint32_t flag);
9791 +extern mpls_return_enum ldp_cfg_peer_test(mpls_cfg_handle handle, ldp_peer * p,
9792 + uint32_t flag);
9793 +extern mpls_return_enum ldp_cfg_peer_set(mpls_cfg_handle handle, ldp_peer * p,
9794 + uint32_t flag);
9796 +extern mpls_return_enum ldp_cfg_fec_get(mpls_cfg_handle handle, mpls_fec * p,
9797 + uint32_t flag);
9798 +extern mpls_return_enum ldp_cfg_fec_getnext(mpls_cfg_handle handle,
9799 + mpls_fec * p, uint32_t flag);
9800 +extern mpls_return_enum ldp_cfg_fec_test(mpls_cfg_handle handle, mpls_fec * p,
9801 + uint32_t flag);
9802 +extern mpls_return_enum ldp_cfg_fec_set(mpls_cfg_handle handle, mpls_fec * p,
9803 + uint32_t flag);
9805 +extern mpls_return_enum ldp_cfg_fec_nexthop_get(mpls_cfg_handle handle,
9806 + mpls_fec * p, mpls_nexthop *nh, uint32_t flag);
9807 +extern mpls_return_enum ldp_cfg_fec_nexthop_getnext(mpls_cfg_handle handle,
9808 + mpls_fec * p, mpls_nexthop *nh, uint32_t flag);
9809 +extern mpls_return_enum ldp_cfg_fec_nexthop_test(mpls_cfg_handle handle,
9810 + mpls_fec * p, mpls_nexthop *nh, uint32_t flag);
9811 +extern mpls_return_enum ldp_cfg_fec_nexthop_set(mpls_cfg_handle handle,
9812 + mpls_fec * p, mpls_nexthop *nh, uint32_t flag);
9814 +extern mpls_return_enum ldp_cfg_addr_get(mpls_cfg_handle handle, ldp_addr * a,
9815 + uint32_t flag);
9816 +extern mpls_return_enum ldp_cfg_addr_getnext(mpls_cfg_handle handle,
9817 + ldp_addr * a, uint32_t flag);
9819 +extern mpls_return_enum ldp_cfg_if_get(mpls_cfg_handle handle, ldp_if * i,
9820 + uint32_t flag);
9821 +extern mpls_return_enum ldp_cfg_if_getnext(mpls_cfg_handle handle, ldp_if * i,
9822 + uint32_t flag);
9823 +extern mpls_return_enum ldp_cfg_if_test(mpls_cfg_handle handle, ldp_if * i,
9824 + uint32_t flag);
9825 +extern mpls_return_enum ldp_cfg_if_set(mpls_cfg_handle handle, ldp_if * i,
9826 + uint32_t flag);
9828 +extern mpls_return_enum ldp_cfg_if_addr_get(mpls_cfg_handle handle, ldp_if * i,
9829 + ldp_addr * a, uint32_t flag);
9830 +extern mpls_return_enum ldp_cfg_if_addr_getnext(mpls_cfg_handle handle,
9831 + ldp_if * i, ldp_addr *a, uint32_t flag);
9832 +extern mpls_return_enum ldp_cfg_if_addr_set(mpls_cfg_handle handle, ldp_if *i,
9833 + ldp_addr * a, uint32_t flag);
9835 +extern mpls_return_enum ldp_cfg_labelrange_get(mpls_cfg_handle handle,
9836 + mpls_range * r, uint32_t flag);
9837 +extern mpls_return_enum ldp_cfg_labelrange_test(mpls_cfg_handle handle,
9838 + mpls_range * r, uint32_t flag);
9839 +extern mpls_return_enum ldp_cfg_labelrange_set(mpls_cfg_handle handle,
9840 + mpls_range * r, uint32_t flag);
9842 +extern mpls_return_enum ldp_cfg_adj_get(mpls_cfg_handle handle, ldp_adj * a,
9843 + uint32_t flag);
9844 +extern mpls_return_enum ldp_cfg_adj_getnext(mpls_cfg_handle handle, ldp_adj * a,
9845 + uint32_t flag);
9846 +extern mpls_return_enum ldp_cfg_adj_entity_getnext(mpls_cfg_handle handle,
9847 + ldp_adj * a);
9849 +extern mpls_return_enum ldp_cfg_session_get(mpls_cfg_handle handle,
9850 + ldp_session * s, uint32_t flag);
9851 +extern mpls_return_enum ldp_cfg_session_getnext(mpls_cfg_handle handle,
9852 + ldp_session * s, uint32_t flag);
9854 +extern mpls_return_enum ldp_cfg_session_raddr_get(mpls_cfg_handle handle,
9855 + ldp_session * s, ldp_addr * a, uint32_t flag);
9856 +extern mpls_return_enum ldp_cfg_session_raddr_getnext(mpls_cfg_handle handle,
9857 + ldp_session * s, ldp_addr * a, uint32_t flag);
9859 +extern mpls_return_enum ldp_cfg_inlabel_get(mpls_cfg_handle handle,
9860 + ldp_inlabel * i, uint32_t flag);
9861 +mpls_return_enum ldp_cfg_inlabel_getnext(mpls_cfg_handle handle,
9862 + ldp_inlabel * i, uint32_t flag);
9863 +extern mpls_return_enum ldp_cfg_outlabel_get(mpls_cfg_handle handle,
9864 + ldp_outlabel * o, uint32_t flag);
9865 +mpls_return_enum ldp_cfg_outlabel_getnext(mpls_cfg_handle handle,
9866 + ldp_outlabel * o, uint32_t flag);
9868 +extern mpls_return_enum ldp_cfg_range_set(mpls_cfg_handle handle,
9869 + mpls_range * r, uint32_t flag);
9870 +extern mpls_return_enum ldp_cfg_range_test(mpls_cfg_handle handle,
9871 + mpls_range * r, uint32_t flag);
9872 +extern mpls_return_enum ldp_cfg_range_get(mpls_cfg_handle handle,
9873 + mpls_range * r, uint32_t flag);
9875 +extern mpls_return_enum ldp_cfg_tunnel_set(mpls_cfg_handle handle,
9876 + ldp_tunnel * r, uint32_t flag);
9877 +extern mpls_return_enum ldp_cfg_tunnel_test(mpls_cfg_handle handle,
9878 + ldp_tunnel * r, uint32_t flag);
9879 +extern mpls_return_enum ldp_cfg_tunnel_get(mpls_cfg_handle handle,
9880 + ldp_tunnel * r, uint32_t flag);
9882 +extern mpls_return_enum ldp_cfg_resource_set(mpls_cfg_handle handle,
9883 + ldp_resource * r, uint32_t flag);
9884 +extern mpls_return_enum ldp_cfg_resource_test(mpls_cfg_handle handle,
9885 + ldp_resource * r, uint32_t flag);
9886 +extern mpls_return_enum ldp_cfg_resource_get(mpls_cfg_handle handle,
9887 + ldp_resource * r, uint32_t flag);
9889 +extern mpls_return_enum ldp_cfg_hop_set(mpls_cfg_handle handle, ldp_hop * r,
9890 + uint32_t flag);
9891 +extern mpls_return_enum ldp_cfg_hop_test(mpls_cfg_handle handle, ldp_hop * r,
9892 + uint32_t flag);
9893 +extern mpls_return_enum ldp_cfg_hop_get(mpls_cfg_handle handle, ldp_hop * r,
9894 + uint32_t flag);
9896 +#endif
9897 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldpd.conf.sample quagga-mpls/ldpd/ldpd.conf.sample
9898 --- quagga/ldpd/ldpd.conf.sample 1969-12-31 18:00:00.000000000 -0600
9899 +++ quagga-mpls/ldpd/ldpd.conf.sample 2006-08-09 22:02:25.000000000 -0500
9900 @@ -0,0 +1,17 @@
9902 +! Zebra configuration saved from vty
9903 +! 2002/03/23 17:07:30
9905 +hostname uml-1
9906 +password root
9907 +enable password root
9909 +mpls ip
9911 +interface lo
9913 +interface eth0
9914 + mpls ip
9916 +line vty
9918 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_defaults.h quagga-mpls/ldpd/ldp_defaults.h
9919 --- quagga/ldpd/ldp_defaults.h 1969-12-31 18:00:00.000000000 -0600
9920 +++ quagga-mpls/ldpd/ldp_defaults.h 2006-08-09 21:56:13.000000000 -0500
9921 @@ -0,0 +1,55 @@
9924 + * Copyright (C) James R. Leu 2000
9925 + * jleu@mindspring.com
9927 + * This software is covered under the LGPL, for more
9928 + * info check out http://www.gnu.org/copyleft/lgpl.html
9929 + */
9931 +#ifndef _LDP_DEFAULTS_H_
9932 +#define _LDP_DEFAULTS_H_
9934 +#define LDP_GLOBAL_DEF_CONTROL_MODE LDP_CONTROL_ORDERED
9935 +#define LDP_GLOBAL_DEF_RETENTION_MODE LDP_RETENTION_LIBERAL
9936 +#define LDP_GLOBAL_DEF_REPAIR_MODE LDP_REPAIR_GLOBAL
9937 +#define LDP_GLOBAL_DEF_PROPOGATE_RELEASE MPLS_BOOL_TRUE
9938 +#define LDP_GLOBAL_DEF_LABEL_MERGE MPLS_BOOL_TRUE
9939 +#define LDP_GLOBAL_DEF_LOOP_DETECTION_MODE LDP_LOOP_NONE
9940 +#define LDP_GLOBAL_DEF_TTLLESS_DOMAIN MPLS_BOOL_FALSE
9941 +#define LDP_GLOBAL_DEF_LOCAL_TCP_PORT 646
9942 +#define LDP_GLOBAL_DEF_LOCAL_UDP_PORT 646
9943 +#define LDP_GLOBAL_DEF_SEND_ADDR_MSG MPLS_BOOL_TRUE
9944 +#define LDP_GLOBAL_DEF_BACKOFF_STEP 15
9945 +#define LDP_GLOBAL_DEF_SEND_LSRID_MAPPING MPLS_BOOL_TRUE
9946 +#define LDP_GLOBAL_DEF_NO_ROUTE_RETRY_TIME 10
9948 +#define LDP_ENTITY_DEF_TRANS_ADDR 0
9949 +#define LDP_ENTITY_DEF_PROTO_VER 1
9950 +#define LDP_ENTITY_DEF_REMOTE_TCP 646
9951 +#define LDP_ENTITY_DEF_REMOTE_UDP 646
9952 +#define LDP_ENTITY_DEF_MAX_PDU 4096
9953 +#define LDP_ENTITY_DEF_KEEPALIVE_TIMER 45
9954 +#define LDP_ENTITY_DEF_KEEPALIVE_INTERVAL 15
9955 +#define LDP_ENTITY_DEF_HELLOTIME_TIMER 15
9956 +#define LDP_ENTITY_DEF_HELLOTIME_INTERVAL 5
9957 +#define LDP_ENTITY_DEF_SESSIONSETUP_COUNT LDP_INFINIT
9958 +#define LDP_ENTITY_DEF_SESSION_BACKOFF_TIMER 10
9959 +#define LDP_ENTITY_DEF_DISTRIBUTION_MODE LDP_DISTRIBUTION_UNSOLICITED
9960 +#define LDP_ENTITY_DEF_PATHVECTOR_LIMIT 10
9961 +#define LDP_ENTITY_DEF_HOPCOUNT_LIMIT 30
9962 +#define LDP_ENTITY_DEF_REQUEST_TIMER 30
9963 +#define LDP_ENTITY_DEF_REQUEST_COUNT LDP_INFINIT
9964 +#define LDP_ENTITY_DEF_REQUIRE_HOPCOUNT MPLS_BOOL_FALSE
9966 +/* you can infer this from REQUEST_COUNT */
9967 +#define LDP_ENTITY_DEF_REQUEST_RETRY MPLS_BOOL_TRUE
9968 +#define LDP_ENTITY_DEF_INHERIT_FLAG LDP_ENTITY_CFG_TRANS_ADDR|\
9969 + LDP_ENTITY_CFG_KEEPALIVE_TIMER|\
9970 + LDP_ENTITY_CFG_KEEPALIVE_INTERVAL|\
9971 + LDP_ENTITY_CFG_HELLOTIME_TIMER|\
9972 + LDP_ENTITY_CFG_HELLOTIME_INTERVAL
9974 +#define LDP_REQUEST_CHUNK 2
9976 +#endif
9977 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_entity.c quagga-mpls/ldpd/ldp_entity.c
9978 --- quagga/ldpd/ldp_entity.c 1969-12-31 18:00:00.000000000 -0600
9979 +++ quagga-mpls/ldpd/ldp_entity.c 2006-12-07 22:10:48.000000000 -0600
9980 @@ -0,0 +1,328 @@
9983 + * Copyright (C) James R. Leu 2000
9984 + * jleu@mindspring.com
9986 + * This software is covered under the LGPL, for more
9987 + * info check out http://www.gnu.org/copyleft/lgpl.html
9988 + */
9990 +#include <stdlib.h>
9991 +#include <string.h>
9992 +#include <netinet/in.h>
9993 +#include <stdio.h>
9994 +#include "ldp_struct.h"
9995 +#include "mpls_assert.h"
9996 +#include "ldp_session.h"
9997 +#include "ldp_global.h"
9998 +#include "ldp_entity.h"
9999 +#include "ldp_hello.h"
10000 +#include "ldp_peer.h"
10001 +#include "ldp_adj.h"
10002 +#include "ldp_if.h"
10003 +#include "ldp_inet_addr.h"
10004 +#include "ldp_mesg.h"
10005 +#include "ldp_cfg.h"
10007 +#include "mpls_mm_impl.h"
10008 +#include "mpls_timer_impl.h"
10009 +#include "mpls_socket_impl.h"
10010 +#include "mpls_trace_impl.h"
10012 +static uint32_t _ldp_entity_next_index = 1;
10014 +void ldp_entity_set_defaults(ldp_entity *e) {
10015 + memset(e, 0, sizeof(ldp_entity));
10017 + e->entity_type = LDP_UNKNOWN;
10019 + if (LDP_ENTITY_DEF_TRANS_ADDR != 0) {
10020 + e->transport_address.type = MPLS_FAMILY_IPV4;
10021 + e->transport_address.u.ipv4 = LDP_ENTITY_DEF_TRANS_ADDR;
10023 + e->protocol_version = LDP_ENTITY_DEF_PROTO_VER;
10024 + e->remote_tcp_port = LDP_ENTITY_DEF_REMOTE_TCP;
10025 + e->remote_udp_port = LDP_ENTITY_DEF_REMOTE_UDP;
10026 + e->max_pdu = LDP_ENTITY_DEF_MAX_PDU;
10027 + e->keepalive_timer = LDP_ENTITY_DEF_KEEPALIVE_TIMER;
10028 + e->keepalive_interval = LDP_ENTITY_DEF_KEEPALIVE_INTERVAL;
10029 + e->hellotime_timer = LDP_ENTITY_DEF_HELLOTIME_TIMER;
10030 + e->hellotime_interval = LDP_ENTITY_DEF_HELLOTIME_INTERVAL;
10031 + e->session_setup_count = LDP_ENTITY_DEF_SESSIONSETUP_COUNT;
10032 + e->session_backoff_timer = LDP_ENTITY_DEF_SESSION_BACKOFF_TIMER;
10033 + e->label_distribution_mode = LDP_ENTITY_DEF_DISTRIBUTION_MODE;
10034 + e->path_vector_limit = LDP_ENTITY_DEF_PATHVECTOR_LIMIT;
10035 + e->hop_count_limit = LDP_ENTITY_DEF_HOPCOUNT_LIMIT;
10036 + e->label_request_timer = LDP_ENTITY_DEF_REQUEST_TIMER;
10037 + e->label_request_count = LDP_ENTITY_DEF_REQUEST_COUNT;
10038 + e->inherit_flag = LDP_ENTITY_DEF_INHERIT_FLAG;
10039 + e->admin_state = MPLS_ADMIN_DISABLE;
10040 + e->remote_in_ttl_less_domain = MPLS_BOOL_FALSE;
10041 + e->request_retry = LDP_ENTITY_DEF_REQUEST_RETRY;
10044 +ldp_entity *ldp_entity_create()
10046 + ldp_entity *e = (ldp_entity *) mpls_malloc(sizeof(ldp_entity));
10048 + if (e) {
10049 + memset(e, 0, sizeof(ldp_entity));
10050 + ldp_entity_set_defaults(e);
10052 + MPLS_REFCNT_INIT(e, 0);
10053 + MPLS_LIST_ELEM_INIT(e, _global);
10054 + MPLS_LIST_INIT(&e->adj_root, ldp_adj);
10056 + e->index = _ldp_entity_get_next_index();
10058 + return e;
10061 +void ldp_entity_delete(ldp_entity * e)
10063 + LDP_PRINT(NULL, "entity delete %p", e);
10064 + MPLS_REFCNT_ASSERT(e, 0);
10065 + mpls_free(e);
10068 +int ldp_entity_label_space(ldp_entity * e)
10070 + if (e) {
10071 + switch (e->entity_type) {
10072 + case LDP_DIRECT:
10073 + return e->p.iff->label_space;
10074 + case LDP_INDIRECT:
10075 + return e->p.peer->label_space;
10076 + default:
10077 + MPLS_ASSERT(0);
10080 + return -1;
10083 +mpls_bool ldp_entity_is_active(ldp_entity * e)
10085 + if (e && e->admin_state == MPLS_ADMIN_ENABLE)
10086 + return MPLS_BOOL_TRUE;
10088 + return MPLS_BOOL_FALSE;
10091 +mpls_bool ldp_entity_is_ready(ldp_entity * e)
10093 + if (e) {
10094 + switch (e->entity_type) {
10095 + case LDP_DIRECT:
10096 + if (e->p.iff)
10097 + return MPLS_BOOL_TRUE;
10098 + break;
10099 + case LDP_INDIRECT:
10100 + if (e->p.peer)
10101 + return MPLS_BOOL_TRUE;
10102 + break;
10103 + default:
10104 + MPLS_ASSERT(0);
10107 + return MPLS_BOOL_FALSE;
10110 +mpls_return_enum ldp_entity_startup(ldp_global * g, ldp_entity * e)
10112 + mpls_return_enum retval = MPLS_FAILURE;
10114 + MPLS_ASSERT(g && e && e->p.iff);
10116 + LDP_ENTER(g->user_data, "ldp_entity_startup");
10118 + if (g->admin_state == MPLS_ADMIN_ENABLE) {
10119 + if (e->inherit_flag & LDP_ENTITY_CFG_TRANS_ADDR) {
10120 + memcpy(&e->transport_address, &g->transport_address,
10121 + sizeof(mpls_inet_addr));
10123 + if (e->inherit_flag & LDP_ENTITY_CFG_KEEPALIVE_TIMER) {
10124 + e->keepalive_timer = g->keepalive_timer;
10126 + if (e->inherit_flag & LDP_ENTITY_CFG_KEEPALIVE_INTERVAL) {
10127 + e->keepalive_interval = g->keepalive_interval;
10129 + if (e->inherit_flag & LDP_ENTITY_CFG_HELLOTIME_TIMER) {
10130 + e->hellotime_timer = g->hellotime_timer;
10132 + if (e->inherit_flag & LDP_ENTITY_CFG_HELLOTIME_INTERVAL) {
10133 + e->hellotime_interval = g->hellotime_interval;
10136 + e->loop_detection_mode = g->loop_detection_mode;
10138 + switch (e->entity_type) {
10139 + case LDP_DIRECT:
10140 + retval = ldp_if_startup(g, e->p.iff);
10141 + break;
10142 + case LDP_INDIRECT:
10143 + retval = ldp_peer_startup(g, e->p.peer);
10144 + break;
10145 + default:
10146 + MPLS_ASSERT(0);
10148 + } else {
10149 + LDP_PRINT(g->user_data, "ldp_entity_startup: global not enabled\n");
10150 + retval = MPLS_SUCCESS;
10153 + if (retval == MPLS_SUCCESS) {
10154 + e->admin_state = MPLS_ADMIN_ENABLE;
10157 + LDP_EXIT(g->user_data, "ldp_entity_startup");
10159 + return retval;
10162 +mpls_return_enum ldp_entity_shutdown(ldp_global * g, ldp_entity * e,
10163 + int global_shutdown)
10165 + ldp_adj *adj = NULL;
10167 + MPLS_ASSERT(g && e);
10169 + LDP_ENTER(g->user_data, "ldp_entity_shutdown");
10171 + if (g->admin_state == MPLS_ADMIN_ENABLE) {
10172 + if (!global_shutdown) {
10173 + e->admin_state = MPLS_ADMIN_DISABLE;
10176 + switch (e->entity_type) {
10177 + case LDP_DIRECT:
10178 + if (ldp_if_shutdown(g, e->p.iff) != MPLS_SUCCESS) {
10179 + LDP_PRINT(g->user_data,
10180 + "ldp_entity_shutdown: shut down of if failed\n");
10182 + break;
10183 + case LDP_INDIRECT:
10184 + if (ldp_peer_shutdown(g, e->p.peer) != MPLS_SUCCESS) {
10185 + LDP_PRINT(g->user_data,
10186 + "ldp_entity_shutdown: shut down of peer failed\n");
10188 + break;
10189 + default:
10190 + MPLS_ASSERT(0);
10193 + while ((adj = MPLS_LIST_HEAD(&e->adj_root))) {
10194 + /* ldp_adj_shutdown() does a ldp_entity_del_adj(e,adj) */
10195 + ldp_adj_shutdown(g, adj);
10197 + } else {
10198 + LDP_PRINT(g->user_data, "ldp_entity_shutdown: global not enabled\n");
10199 + e->admin_state = MPLS_ADMIN_DISABLE;
10202 + LDP_EXIT(g->user_data, "ldp_entity_shutdown");
10204 + return MPLS_SUCCESS;
10207 +uint32_t _ldp_entity_get_next_index()
10209 + uint32_t retval = _ldp_entity_next_index;
10211 + _ldp_entity_next_index++;
10212 + if (retval > _ldp_entity_next_index) {
10213 + _ldp_entity_next_index = 1;
10215 + return retval;
10218 +void ldp_entity_add_if(ldp_entity * e, ldp_if * i)
10220 + MPLS_ASSERT(e && i && e->entity_type == LDP_UNKNOWN);
10222 + e->entity_type = LDP_DIRECT;
10223 + MPLS_REFCNT_HOLD(i);
10224 + e->p.iff = i;
10225 + e->sub_index = i->index;
10226 + _ldp_if_add_entity(i, e);
10229 +void ldp_entity_del_if(ldp_global * g, ldp_entity * e)
10231 + MPLS_ASSERT(e && e->entity_type == LDP_DIRECT && e->p.iff);
10232 + _ldp_if_del_entity(e->p.iff);
10233 + MPLS_REFCNT_RELEASE2(g, e->p.iff, ldp_if_delete);
10234 + e->p.iff = NULL;
10235 + e->entity_type = LDP_UNKNOWN;
10236 + e->sub_index = 0;
10239 +void ldp_entity_add_peer(ldp_entity * e, ldp_peer * p)
10241 + MPLS_ASSERT(e && e->entity_type == LDP_UNKNOWN);
10243 + e->entity_type = LDP_INDIRECT;
10244 + MPLS_REFCNT_HOLD(p);
10245 + e->p.peer = p;
10246 + e->sub_index = p->index;
10247 + _ldp_peer_add_entity(p, e);
10250 +void ldp_entity_del_peer(ldp_entity * e)
10252 + MPLS_ASSERT(e && e->entity_type == LDP_INDIRECT && e->p.peer);
10253 + _ldp_peer_del_entity(e->p.peer);
10254 + MPLS_REFCNT_RELEASE(e->p.peer, ldp_peer_delete);
10255 + e->p.peer = NULL;
10256 + e->entity_type = LDP_UNKNOWN;
10257 + e->sub_index = 0;
10260 +void ldp_entity_add_adj(ldp_entity * e, ldp_adj * a)
10262 + ldp_adj *ap = NULL;
10264 + MPLS_ASSERT(e && a);
10265 + MPLS_REFCNT_HOLD(a);
10267 + _ldp_adj_add_entity(a, e);
10268 + ap = MPLS_LIST_HEAD(&e->adj_root);
10269 + while (ap) {
10270 + if (ap->index > a->index) {
10271 + MPLS_LIST_INSERT_BEFORE(&e->adj_root, ap, a, _entity);
10272 + return;
10274 + ap = MPLS_LIST_NEXT(&e->adj_root, ap, _entity);
10276 + MPLS_LIST_ADD_TAIL(&e->adj_root, a, _entity, ldp_adj);
10279 +void ldp_entity_del_adj(ldp_entity * e, ldp_adj * a)
10281 + MPLS_ASSERT(e && a);
10282 + MPLS_LIST_REMOVE(&e->adj_root, a, _entity);
10283 + _ldp_adj_del_entity(a, e);
10284 + MPLS_REFCNT_RELEASE(a, ldp_adj_delete);
10287 +ldp_adj *ldp_entity_find_adj(ldp_entity * e, ldp_mesg * msg)
10289 + ldp_adj *a = NULL;
10290 + mpls_inet_addr lsraddr;
10291 + int labelspace;
10293 + MPLS_ASSERT(e);
10295 + ldp_mesg_hdr_get_labelspace(msg, &labelspace);
10296 + ldp_mesg_hdr_get_lsraddr(msg, &lsraddr);
10298 + a = MPLS_LIST_HEAD(&e->adj_root);
10299 + while (a != NULL) {
10300 + if (a->remote_label_space == labelspace &&
10301 + (!mpls_inet_addr_compare(&lsraddr, &a->remote_lsr_address))) {
10302 + return a;
10304 + a = MPLS_LIST_NEXT(&e->adj_root, a, _entity);
10307 + return NULL;
10309 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_entity.h quagga-mpls/ldpd/ldp_entity.h
10310 --- quagga/ldpd/ldp_entity.h 1969-12-31 18:00:00.000000000 -0600
10311 +++ quagga-mpls/ldpd/ldp_entity.h 2006-08-09 21:56:14.000000000 -0500
10312 @@ -0,0 +1,45 @@
10315 + * Copyright (C) James R. Leu 2000
10316 + * jleu@mindspring.com
10318 + * This software is covered under the LGPL, for more
10319 + * info check out http://www.gnu.org/copyleft/lgpl.html
10320 + */
10322 +#ifndef _LDP_ENTITY_H_
10323 +#define _LDP_ENTITY_H_
10325 +#include "ldp_struct.h"
10327 +extern void ldp_entity_set_defaults(ldp_entity *e);
10328 +extern ldp_entity *ldp_entity_create();
10329 +extern void ldp_entity_delete(ldp_entity * e);
10330 +extern mpls_bool ldp_entity_is_active(ldp_entity * e);
10331 +extern mpls_bool ldp_entity_is_ready(ldp_entity * e);
10332 +extern int ldp_entity_label_space(ldp_entity * e);
10333 +extern ldp_mesg *ldp_entity_get_message(ldp_entity * e);
10335 +extern mpls_return_enum ldp_entity_startup(ldp_global * g, ldp_entity * e);
10336 +extern mpls_return_enum ldp_entity_shutdown(ldp_global * g, ldp_entity * e,
10337 + int flag);
10339 +extern void ldp_entity_register(ldp_global * g, ldp_entity * e);
10340 +extern void ldp_entity_unregister(ldp_global * g, ldp_entity * e);
10342 +extern void ldp_entity_add_if(ldp_entity * e, ldp_if * i);
10343 +extern void ldp_entity_del_if(ldp_global * g, ldp_entity * e);
10345 +extern void ldp_entity_add_peer(ldp_entity * e, ldp_peer * p);
10346 +extern void ldp_entity_del_peer(ldp_entity * e);
10348 +extern void ldp_entity_add_adj(ldp_entity * e, ldp_adj * a);
10349 +extern void ldp_entity_del_adj(ldp_entity * e, ldp_adj * a);
10350 +extern ldp_adj *ldp_entity_find_adj(ldp_entity * e, ldp_mesg * msg);
10352 +extern mpls_return_enum ldp_entity_set_admin_state(ldp_global * g,
10353 + ldp_entity * e, mpls_admin_state_enum state);
10355 +extern uint32_t _ldp_entity_get_next_index();
10357 +#endif
10358 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_fec.c quagga-mpls/ldpd/ldp_fec.c
10359 --- quagga/ldpd/ldp_fec.c 1969-12-31 18:00:00.000000000 -0600
10360 +++ quagga-mpls/ldpd/ldp_fec.c 2006-12-07 22:10:05.000000000 -0600
10361 @@ -0,0 +1,608 @@
10364 + * Copyright (C) James R. Leu 2000
10365 + * jleu@mindspring.com
10367 + * This software is covered under the LGPL, for more
10368 + * info check out http://www.gnu.org/copyleft/lgpl.html
10369 + */
10371 +#include "ldp_struct.h"
10372 +#include "ldp_fec.h"
10373 +#include "ldp_if.h"
10374 +#include "ldp_attr.h"
10375 +#include "ldp_addr.h"
10376 +#include "ldp_nexthop.h"
10377 +#include "ldp_session.h"
10378 +#include "ldp_inlabel.h"
10379 +#include "ldp_outlabel.h"
10380 +#include "ldp_global.h"
10381 +#include "ldp_label_mapping.h"
10382 +#include "ldp_label_request.h"
10383 +#include "ldp_label_abort.h"
10384 +#include "ldp_label_rel_with.h"
10385 +#include "mpls_assert.h"
10386 +#include "mpls_compare.h"
10387 +#include "mpls_mm_impl.h"
10388 +#include "mpls_tree_impl.h"
10389 +#include "mpls_policy_impl.h"
10390 +#include "mpls_trace_impl.h"
10392 +#if MPLS_USE_LSR
10393 +#include "lsr_cfg.h"
10394 +#else
10395 +#include "mpls_mpls_impl.h"
10396 +#endif
10398 +static uint32_t _ldp_fec_next_index = 1;
10400 +static mpls_return_enum ldp_fec_insert(ldp_global *g, ldp_fec * fec)
10402 + mpls_return_enum retval = MPLS_SUCCESS;
10403 + uint32_t key;
10404 + uint8_t len;
10406 + MPLS_ASSERT(g && fec);
10407 + LDP_ENTER(g->user_data, "ldp_fec_insert");
10409 + switch(fec->info.type) {
10410 + case MPLS_FEC_PREFIX:
10411 + key = fec->info.u.prefix.network.u.ipv4;
10412 + len = fec->info.u.prefix.length;
10413 + break;
10414 + case MPLS_FEC_HOST:
10415 + key = fec->info.u.host.u.ipv4;
10416 + len = 32;
10417 + break;
10418 + case MPLS_FEC_L2CC:
10419 + /* they had better insert it into the global list */
10420 + LDP_EXIT(g->user_data, "ldp_fec_insert: l2cc");
10421 + return MPLS_SUCCESS;
10422 + default:
10423 + MPLS_ASSERT(0);
10426 + LDP_PRINT(g->user_data, "ldp_fec_insert: 0x%08x/%d\n", key, len);
10428 + if (mpls_tree_insert(g->fec_tree, key, len, (void *)fec) != MPLS_SUCCESS) {
10429 + LDP_PRINT(g->user_data, "ldp_fec_insert: error adding fec\n");
10430 + retval = MPLS_FATAL;
10433 + LDP_EXIT(g->user_data, "ldp_fec_insert");
10434 + return retval;
10437 +static void ldp_fec_remove(ldp_global *g, mpls_fec *fec)
10439 + ldp_fec *f = NULL;
10440 + uint32_t key;
10441 + uint8_t len;
10443 + MPLS_ASSERT(g && fec);
10444 + LDP_ENTER(g->user_data, "ldp_fec_remove");
10446 + switch(fec->type) {
10447 + case MPLS_FEC_PREFIX:
10448 + key = fec->u.prefix.network.u.ipv4;
10449 + len = fec->u.prefix.length;
10450 + break;
10451 + case MPLS_FEC_HOST:
10452 + key = fec->u.host.u.ipv4;
10453 + len = 32;
10454 + break;
10455 + case MPLS_FEC_L2CC:
10456 + /* they had better remove it from the global list */
10457 + LDP_EXIT(g->user_data, "ldp_fec_remove");
10458 + return;
10459 + default:
10460 + MPLS_ASSERT(0);
10463 + LDP_PRINT(g->user_data, "ldp_fec_remove: 0x%08x/%d\n", key, len);
10464 + mpls_tree_remove(g->fec_tree, key, len, (void **)&f);
10466 + MPLS_ASSERT(f);
10468 + LDP_EXIT(g->user_data, "ldp_fec_remove");
10471 +static uint32_t _ldp_fec_get_next_index()
10473 + uint32_t retval = _ldp_fec_next_index;
10475 + _ldp_fec_next_index++;
10476 + if (retval > _ldp_fec_next_index) {
10477 + _ldp_fec_next_index = 1;
10479 + return retval;
10482 +ldp_fec *ldp_fec_create(ldp_global *g, mpls_fec *f)
10484 + ldp_fec *fec = (ldp_fec *) mpls_malloc(sizeof(ldp_fec));
10486 + if (fec != NULL) {
10487 + memset(fec, 0, sizeof(ldp_fec));
10488 + /*
10489 + * note: this is init to 1 for a reason!
10490 + * We're placing it in the global list, so this is our refcnt
10491 + * when this refcnt gets to zero, it will be removed from the
10492 + * global list and deleted
10493 + */
10494 + /*
10495 + * TESTING: jleu 6/7/2004, since I want the FEC to be cleaned up
10496 + * when it no longer has a nexthop, addr, or label, the only things that
10497 + * should increment the ref are those (nh, addr, label etc), not global
10498 + * nor inserting into the tree. I also added this comment in
10499 + * _ldp_global_add_fec()
10500 + MPLS_REFCNT_INIT(fec, 1);
10501 + */
10502 + MPLS_REFCNT_INIT(fec, 0);
10503 + MPLS_LIST_ELEM_INIT(fec, _global);
10504 + MPLS_LIST_ELEM_INIT(fec, _inlabel);
10505 + MPLS_LIST_ELEM_INIT(fec, _outlabel);
10506 + MPLS_LIST_ELEM_INIT(fec, _fec);
10507 + MPLS_LIST_INIT(&fec->nh_root, ldp_nexthop);
10508 + MPLS_LIST_INIT(&fec->fs_root_us, ldp_fs);
10509 + MPLS_LIST_INIT(&fec->fs_root_ds, ldp_fs);
10510 + fec->index = _ldp_fec_get_next_index();
10511 + fec->is_route = MPLS_BOOL_FALSE;
10512 + mpls_fec2ldp_fec(f,fec);
10514 + _ldp_global_add_fec(g, fec);
10515 + ldp_fec_insert(g, fec);
10517 + return fec;
10520 +void ldp_fec_delete(ldp_global *g, ldp_fec * fec)
10522 + LDP_PRINT(g->user_data, "fec delete: %08x/%d",
10523 + fec->info.u.prefix.network.u.ipv4, fec->info.u.prefix.length);
10524 + ldp_fec_remove(g, &fec->info);
10525 + _ldp_global_del_fec(g, fec);
10526 + mpls_free(fec);
10529 +ldp_fec *ldp_fec_find(ldp_global *g, mpls_fec *fec)
10531 + ldp_fec *f = NULL;
10532 + uint32_t key;
10533 + uint8_t len;
10535 + switch(fec->type) {
10536 + case MPLS_FEC_PREFIX:
10537 + key = fec->u.prefix.network.u.ipv4;
10538 + len = fec->u.prefix.length;
10539 + break;
10540 + case MPLS_FEC_HOST:
10541 + key = fec->u.host.u.ipv4;
10542 + len = 32;
10543 + break;
10544 + case MPLS_FEC_L2CC:
10545 + if (ldp_global_find_fec(g, fec, &f) == MPLS_SUCCESS) {
10546 + return f;
10548 + return NULL;
10549 + default:
10550 + MPLS_ASSERT(0);
10553 + LDP_PRINT(g->user_data, "ldp_fec_find: 0x%08x/%d\n", key, len);
10554 + if (mpls_tree_get(g->fec_tree, key, len, (void **)&f) != MPLS_SUCCESS) {
10555 + return NULL;
10557 + return f;
10560 +ldp_fec *ldp_fec_find2(ldp_global *g, mpls_fec *fec)
10562 + ldp_fec *f = NULL;
10563 + f = ldp_fec_find(g, fec);
10564 + if (!f) {
10565 + f = ldp_fec_create(g, fec);
10567 + return f;
10570 +ldp_nexthop *ldp_fec_nexthop_find(ldp_fec *f, mpls_nexthop *n)
10572 + ldp_nexthop *nh = NULL;
10574 + MPLS_ASSERT(f && n);
10576 + nh = MPLS_LIST_HEAD(&f->nh_root);
10577 + while (nh) {
10578 + if (!mpls_nexthop_compare(&nh->info, n)) {
10579 + return nh;
10581 + nh = MPLS_LIST_NEXT(&f->nh_root, nh, _fec);
10584 + return NULL;
10587 +mpls_return_enum ldp_fec_find_nexthop_index(ldp_fec *f, int index,
10588 + ldp_nexthop **n)
10590 + ldp_nexthop *nh = NULL;
10592 + MPLS_ASSERT(f);
10594 + if (index > 0) {
10596 + /* because we sort our inserts by index, this lets us know
10597 + if we've "walked" past the end of the list */
10599 + nh = MPLS_LIST_TAIL(&f->nh_root);
10600 + if (!nh || nh->index < index) {
10601 + *n = NULL;
10602 + return MPLS_END_OF_LIST;
10605 + nh = MPLS_LIST_HEAD(&f->nh_root);
10606 + do {
10607 + if (nh->index == index) {
10608 + *n = nh;
10609 + return MPLS_SUCCESS;
10611 + } while((nh = MPLS_LIST_NEXT(&f->nh_root, nh, _fec)));
10613 + *n = NULL;
10614 + return MPLS_FAILURE;
10617 +mpls_return_enum ldp_fec_add_nexthop(ldp_global *g, ldp_fec * f,
10618 + ldp_nexthop * nh)
10620 + MPLS_ASSERT(f && nh);
10622 + LDP_ENTER(g->user_data, "ldp_fec_add_nexthop");
10624 + MPLS_REFCNT_HOLD(nh);
10625 + MPLS_LIST_ADD_HEAD(&f->nh_root, nh, _fec, ldp_nexthop);
10627 + ldp_nexthop_add_fec(nh, f);
10629 + LDP_EXIT(g->user_data, "ldp_fec_add_nexthop: success");
10630 + return MPLS_SUCCESS;
10632 +ldp_fec_add_nexthop_error:
10634 + ldp_fec_del_nexthop(g, f, nh);
10635 + LDP_EXIT(g->user_data, "ldp_fec_add_nexthop: fail");
10636 + return MPLS_FATAL;
10639 +void ldp_fec_del_nexthop(ldp_global *g, ldp_fec * f, ldp_nexthop *nh)
10641 + MPLS_ASSERT(f && nh);
10643 + MPLS_LIST_REMOVE(&f->nh_root, nh, _fec);
10644 + ldp_nexthop_del_fec(g, nh);
10645 + MPLS_REFCNT_RELEASE2(g, nh, ldp_nexthop_delete);
10648 +mpls_return_enum ldp_fec_process_add(ldp_global * g, ldp_fec * f,
10649 + ldp_nexthop *nh, ldp_session *nh_session)
10651 + ldp_session *peer = NULL;
10652 + ldp_attr *ds_attr = NULL;
10653 + ldp_attr *us_attr = NULL;
10654 + mpls_bool egress;
10655 + ldp_outlabel *out;
10657 + LDP_ENTER(g->user_data, "ldp_fec_process_add");
10659 + /*
10660 + * find the info about the next hop for this FEC
10661 + */
10662 + if (!nh_session) {
10663 + nh_session = ldp_get_next_hop_session_for_fec2(f, nh);
10666 + if (nh_session) {
10667 + /* check if we've received and retainted a label from nh_session for f */
10668 + ds_attr = ldp_attr_find_downstream_state2(g, nh_session, f,
10669 + LDP_LSP_STATE_MAP_RECV);
10670 + if (ds_attr && !ds_attr->outlabel) {
10671 + /* if so, and we have not installed that label, install it now */
10672 + out = ldp_outlabel_create_complete(g, nh_session, ds_attr, nh);
10673 + if (!out) {
10674 + return MPLS_FAILURE;
10676 + ds_attr->outlabel = out;
10680 + /* are we willing to egress for this FEC */
10681 + egress = mpls_policy_egress_check(g->user_data, &f->info, &nh->info);
10683 + /*
10684 + * for every peer except the nh hop peer, check to see if we need to
10685 + * send a mapping
10686 + */
10687 + peer = MPLS_LIST_HEAD(&g->session);
10688 + while (peer != NULL) { /* FEC.1 */
10689 + if ((peer->state != LDP_STATE_OPERATIONAL) ||
10690 + (nh_session && peer->index == nh_session->index)) {
10691 + goto next_peer;
10693 + /* have I already sent a mapping for FEC to peer */
10694 + if ((us_attr = ldp_attr_find_upstream_state2(g, peer, f,
10695 + LDP_LSP_STATE_MAP_SENT))) {
10696 + /* yep, don't send another */
10697 + if (ds_attr) {
10698 + /* we need to XC the label we sent with the one we already have */
10699 + if (ldp_inlabel_add_outlabel(g, us_attr->inlabel,
10700 + ds_attr->outlabel) != MPLS_SUCCESS) {
10701 + return MPLS_FAILURE;
10704 + goto next_peer;
10707 + /* we need to send a label */
10708 + if (peer->oper_distribution_mode == LDP_DISTRIBUTION_UNSOLICITED) {
10709 + if (g->lsp_control_mode == LDP_CONTROL_INDEPENDENT) {
10710 + /* if we have received a pending request, give that as input to
10711 + * ldp_label_mapping_with_xc */
10712 + us_attr =
10713 + ldp_attr_find_upstream_state2(g, peer, f, LDP_LSP_STATE_REQ_RECV);
10715 + /* FEC.1.DUI3,4 */
10716 + if (ldp_label_mapping_with_xc(g, peer, f, &us_attr, ds_attr) !=
10717 + MPLS_SUCCESS) {
10718 + if (us_attr->in_tree) {
10719 + ldp_attr_remove_complete(g, us_attr, MPLS_BOOL_FALSE);
10721 + goto next_peer;
10723 + } else {
10724 + /*
10725 + *LDP_CONTROL_ORDERED
10726 + */
10728 + if (ds_attr || (egress == MPLS_BOOL_TRUE)) { /* FEC.1.DUO2 */
10729 + /* FEC.1.DUO3-4 */
10731 + /*
10732 + * ldp_label_mapping_with_xc will create a us_attr if
10733 + * one does not exist yet
10734 + */
10735 + if (ldp_label_mapping_with_xc(g, peer, f, &us_attr, ds_attr) !=
10736 + MPLS_SUCCESS) {
10737 + return MPLS_FAILURE;
10742 + next_peer:
10743 + peer = MPLS_LIST_NEXT(&g->session, peer, _global);
10746 + if (ds_attr) { /* FEC.2 */
10747 + /* does this send an updated mapping? */
10748 + if (ldp_label_mapping_process(g, nh_session, NULL, NULL, ds_attr, f) ==
10749 + MPLS_FAILURE) { /* FEC.5 */
10750 + return MPLS_FAILURE;
10752 + return MPLS_SUCCESS;
10755 + /*
10756 + * LDP_DISTRIBUTION_ONDEMAND
10757 + */
10758 + /* FEC.3 */
10759 + if (nh_session &&
10760 + nh_session->oper_distribution_mode == LDP_DISTRIBUTION_ONDEMAND) {
10761 + /* assume we're always "request when needed" */
10762 + ds_attr = NULL;
10763 + if (ldp_label_request_for_xc(g, nh_session, &f->info, NULL, &ds_attr) ==
10764 + MPLS_FAILURE) { /* FEC.4 */
10765 + return MPLS_FAILURE;
10769 + LDP_EXIT(g->user_data, "ldp_fec_process_add");
10771 + return MPLS_SUCCESS; /* FEC.6 */
10774 +mpls_return_enum ldp_fec_process_change(ldp_global * g, ldp_fec * f,
10775 + ldp_nexthop *nh, ldp_nexthop *nh_old, ldp_session *nh_session_old) {
10776 + ldp_session *peer = NULL;
10777 + ldp_attr *us_attr = NULL;
10778 + ldp_attr *ds_attr = NULL;
10779 + ldp_session *nh_session = NULL;
10781 + LDP_ENTER(g->user_data,
10782 + "ldp_fec_process_change: fec %p nh %p nh_old %p nh_session_old %p",
10783 + f, nh, nh_old, nh_session_old);
10785 + if (!nh_session_old) {
10786 + nh_session_old = ldp_session_for_nexthop(nh_old);
10789 + /*
10790 + * NH 1-5 decide if we need to release an existing mapping
10791 + */
10792 + ds_attr = ldp_attr_find_downstream_state2(g, nh_session_old, f,
10793 + LDP_LSP_STATE_MAP_RECV);
10794 + if (!ds_attr) { /* NH.1 */
10795 + goto Detect_Change_Fec_Next_Hop_6;
10798 + if (ds_attr->ingress == MPLS_BOOL_TRUE) {
10800 +#if MPLS_USE_LSR
10801 + lsr_ftn ftn;
10802 + ftn.outsegment_index = ds_attr->outlabel->info.handle;
10803 + memcpy(&ftn.fec, &f->info, sizeof(mpls_fec));
10804 + lsr_cfg_ftn_set2(g->lsr_handle, &ftn, LSR_CFG_DEL);
10805 +#else
10806 + mpls_mpls_fec2out_del(g->mpls_handle, &f->info, &ds_attr->outlabel->info);
10807 +#endif
10808 + ds_attr->ingress = MPLS_BOOL_FALSE;
10809 + ds_attr->outlabel->merge_count--;
10812 + if (g->label_retention_mode == LDP_RETENTION_LIBERAL) { /* NH.3 */
10813 + ldp_attr *us_temp;
10814 + us_attr = MPLS_LIST_HEAD(&ds_attr->us_attr_root);
10815 + while (us_attr) {
10816 + /* need to walk the list in such a way as not to
10817 + * "pull the rug out from under me self"
10818 + */
10819 + us_temp = MPLS_LIST_NEXT(&ds_attr->us_attr_root, us_attr, _ds_attr);
10820 + if (us_attr->state == LDP_LSP_STATE_MAP_SENT) {
10821 + ldp_inlabel_del_outlabel(g, us_attr->inlabel); /* NH.2 */
10822 + ldp_attr_del_us2ds(g, us_attr, ds_attr);
10824 + us_attr = us_temp;
10826 + goto Detect_Change_Fec_Next_Hop_6;
10829 + ldp_label_release_send(g, nh_session_old, ds_attr, LDP_NOTIF_NONE); /* NH.4 */
10830 + ldp_attr_remove_complete(g, ds_attr, MPLS_BOOL_FALSE); /* NH.2,5 */
10832 +Detect_Change_Fec_Next_Hop_6:
10834 + /*
10835 + * NH 6-9 decides is we need to send a label request abort
10836 + */
10837 + ds_attr = ldp_attr_find_downstream_state2(g, nh_session_old, f,
10838 + LDP_LSP_STATE_REQ_SENT);
10839 + if (ds_attr) { /* NH.6 */
10840 + if (g->label_retention_mode != LDP_RETENTION_CONSERVATIVE) { /* NH.7 */
10841 + /* NH.8,9 */
10842 + if (ldp_label_abort_send(g, nh_session_old, ds_attr) != MPLS_SUCCESS) {
10843 + return MPLS_FAILURE;
10848 + /*
10849 + * NH 10-12 decides if we can use a mapping from our database
10850 + */
10851 + if ((!nh) || (!(nh_session = ldp_get_next_hop_session_for_fec2(f,nh)))) {
10852 + goto Detect_Change_Fec_Next_Hop_16;
10855 + ds_attr = ldp_attr_find_downstream_state2(g, nh_session, f,
10856 + LDP_LSP_STATE_MAP_RECV);
10857 + if (!ds_attr) { /* NH.11 */
10858 + goto Detect_Change_Fec_Next_Hop_13;
10861 + if (ldp_label_mapping_process(g, nh_session, NULL, NULL, ds_attr, f) !=
10862 + MPLS_SUCCESS) { /* NH.12 */
10863 + return MPLS_FAILURE;
10865 + goto Detect_Change_Fec_Next_Hop_20;
10867 +Detect_Change_Fec_Next_Hop_13:
10869 + /*
10870 + * NH 13-15 decides if we need to make a label request
10871 + */
10872 + if (nh_session->oper_distribution_mode == LDP_DISTRIBUTION_ONDEMAND &&
10873 + g->label_retention_mode == LDP_RETENTION_CONSERVATIVE) {
10874 + /* NH.14-15 */
10875 + if (ldp_label_request_for_xc(g, nh_session, &f->info, NULL, &ds_attr) !=
10876 + MPLS_SUCCESS) {
10877 + return MPLS_FAILURE;
10880 + goto Detect_Change_Fec_Next_Hop_20;
10882 +Detect_Change_Fec_Next_Hop_16:
10884 + peer = MPLS_LIST_HEAD(&g->session);
10885 + while (peer) {
10886 + if (peer->state == LDP_STATE_OPERATIONAL) {
10887 + us_attr = ldp_attr_find_upstream_state2(g, peer, f,
10888 + LDP_LSP_STATE_MAP_SENT);
10889 + if (us_attr) { /* NH.17 */
10890 + mpls_return_enum retval;
10891 + MPLS_REFCNT_HOLD(us_attr);
10892 + ldp_attr_remove_complete(g, us_attr, MPLS_BOOL_FALSE);
10893 + retval = ldp_label_withdraw_send(g, peer, us_attr, LDP_NOTIF_NONE);
10894 + MPLS_REFCNT_RELEASE2(g, us_attr, ldp_attr_delete);
10895 + if (retval != MPLS_SUCCESS) { /* NH.18 */
10896 + /*
10897 + * I think it is best to exit out immediatly with an error
10898 + * and let the caller do something about it, the only real
10899 + * option is a global reset of LDP
10900 + */
10901 + return MPLS_FAILURE;
10905 + peer = MPLS_LIST_NEXT(&g->session, peer, _global);
10908 +Detect_Change_Fec_Next_Hop_20:
10910 + LDP_EXIT(g->user_data, "ldp_fec_process_change");
10912 + return MPLS_SUCCESS;
10915 +void mpls_fec2ldp_fec(mpls_fec * a, ldp_fec * b)
10917 + memcpy(&b->info, a, sizeof(mpls_fec));
10920 +void mpls_fec2fec_tlv(mpls_fec * lf, mplsLdpFecTlv_t * tlv, int i)
10922 + tlv->fecElArray[i].addressEl.addressFam = 1;
10924 + switch (lf->type) {
10925 + case MPLS_FEC_PREFIX:
10926 + tlv->fecElArray[i].addressEl.type = MPLS_PREFIX_FEC;
10927 + tlv->fecElArray[i].addressEl.preLen = lf->u.prefix.length;
10928 + tlv->fecElArray[i].addressEl.address = lf->u.prefix.network.u.ipv4;
10929 + tlv->fecElemTypes[i] = MPLS_PREFIX_FEC;
10930 + break;
10931 + case MPLS_FEC_HOST:
10932 + tlv->fecElArray[i].addressEl.type = MPLS_HOSTADR_FEC;
10933 + tlv->fecElArray[i].addressEl.preLen = MPLS_IPv4LEN;
10934 + tlv->fecElArray[i].addressEl.address = lf->u.host.u.ipv4;
10935 + tlv->fecElemTypes[i] = MPLS_HOSTADR_FEC;
10936 + break;
10937 + default:
10938 + MPLS_ASSERT(0);
10942 +void fec_tlv2mpls_fec(mplsLdpFecTlv_t * tlv, int i, mpls_fec * lf) {
10943 + switch (tlv->fecElemTypes[i]) {
10944 + case MPLS_PREFIX_FEC:
10945 + lf->type = MPLS_FEC_PREFIX;
10946 + lf->u.prefix.length = tlv->fecElArray[i].addressEl.preLen;
10947 + lf->u.prefix.network.u.ipv4 = tlv->fecElArray[i].addressEl.address;
10948 + lf->u.prefix.network.type = MPLS_FAMILY_IPV4;
10949 + break;
10950 + case MPLS_HOSTADR_FEC:
10951 + lf->type = MPLS_FEC_HOST;
10952 + lf->u.host.u.ipv4 = tlv->fecElArray[i].addressEl.address;
10953 + lf->u.host.type = MPLS_FAMILY_IPV4;
10954 + break;
10955 + default:
10956 + MPLS_ASSERT(0);
10960 +mpls_bool ldp_fec_empty(ldp_fec *fec)
10962 + if (MPLS_LIST_EMPTY(&fec->fs_root_us) &&
10963 + MPLS_LIST_EMPTY(&fec->nh_root) &&
10964 + MPLS_LIST_EMPTY(&fec->fs_root_ds)) {
10965 + return MPLS_BOOL_TRUE;
10967 + return MPLS_BOOL_FALSE;
10970 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_fec.h quagga-mpls/ldpd/ldp_fec.h
10971 --- quagga/ldpd/ldp_fec.h 1969-12-31 18:00:00.000000000 -0600
10972 +++ quagga-mpls/ldpd/ldp_fec.h 2006-08-09 21:56:11.000000000 -0500
10973 @@ -0,0 +1,34 @@
10976 + * Copyright (C) James R. Leu 2000
10977 + * jleu@mindspring.com
10979 + * This software is covered under the LGPL, for more
10980 + * info check out http://www.gnu.org/copyleft/lgpl.html
10981 + */
10983 +#ifndef _LDP_FEC_H_
10984 +#define _LDP_FEC_H_
10986 +extern ldp_fec *ldp_fec_create(ldp_global *g, mpls_fec *fec);
10987 +extern void ldp_fec_delete(ldp_global *g, ldp_fec * fec);
10988 +extern ldp_fec *ldp_fec_find(ldp_global *g, mpls_fec *fec);
10989 +extern ldp_fec *ldp_fec_find2(ldp_global *g, mpls_fec *fec);
10990 +extern ldp_nexthop *ldp_fec_nexthop_find(ldp_fec *f, mpls_nexthop *n);
10991 +extern mpls_return_enum ldp_fec_find_nexthop_index(ldp_fec *f, int index,
10992 + ldp_nexthop **n);
10993 +extern mpls_return_enum ldp_fec_add_nexthop(ldp_global *g, ldp_fec *f,
10994 + ldp_nexthop *n);
10995 +extern void ldp_fec_del_nexthop(ldp_global *g, ldp_fec *f, ldp_nexthop *n);
10997 +extern mpls_return_enum ldp_fec_process_add(ldp_global * g, ldp_fec * f,
10998 + ldp_nexthop *nh, ldp_session *nh_session);
10999 +extern mpls_return_enum ldp_fec_process_change(ldp_global * g, ldp_fec * f,
11000 + ldp_nexthop *nh, ldp_nexthop *nh_old, ldp_session * nh_session_old);
11002 +extern mpls_bool ldp_fec_empty(ldp_fec *fec);
11003 +extern void mpls_fec2ldp_fec(mpls_fec * a, ldp_fec * b);
11004 +extern void fec_tlv2mpls_fec(mplsLdpFecTlv_t * tlv, int num, mpls_fec * lf);
11005 +extern void mpls_fec2fec_tlv(mpls_fec * lf, mplsLdpFecTlv_t * tlv, int num);
11007 +#endif
11008 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_global.c quagga-mpls/ldpd/ldp_global.c
11009 --- quagga/ldpd/ldp_global.c 1969-12-31 18:00:00.000000000 -0600
11010 +++ quagga-mpls/ldpd/ldp_global.c 2007-04-18 20:03:52.000000000 -0500
11011 @@ -0,0 +1,1296 @@
11014 + * Copyright (C) James R. Leu 2000
11015 + * jleu@mindspring.com
11017 + * This software is covered under the LGPL, for more
11018 + * info check out http://www.gnu.org/copyleft/lgpl.html
11019 + */
11021 +#include <stdlib.h>
11022 +#include <netinet/in.h>
11023 +#include "ldp_struct.h"
11024 +#include "ldp_inet_addr.h"
11025 +#include "ldp_session.h"
11026 +#include "ldp_entity.h"
11027 +#include "ldp_global.h"
11028 +#include "ldp_nexthop.h"
11029 +#include "ldp_outlabel.h"
11030 +#include "ldp_inlabel.h"
11031 +#include "ldp_hello.h"
11032 +#include "ldp_peer.h"
11033 +#include "ldp_attr.h"
11034 +#include "ldp_addr.h"
11035 +#include "ldp_adj.h"
11036 +#include "ldp_fec.h"
11037 +#include "ldp_if.h"
11038 +#include "ldp_label_mapping.h"
11039 +#include "ldp_tunnel.h"
11040 +#include "ldp_resource.h"
11041 +#include "ldp_hop_list.h"
11043 +#include "mpls_compare.h"
11045 +#include "mpls_socket_impl.h"
11046 +#include "mpls_timer_impl.h"
11047 +#include "mpls_ifmgr_impl.h"
11048 +#include "mpls_tree_impl.h"
11049 +#include "mpls_lock_impl.h"
11050 +#include "mpls_fib_impl.h"
11051 +#include "mpls_policy_impl.h"
11052 +#include "mpls_mm_impl.h"
11053 +#include "mpls_trace_impl.h"
11055 +#if MPLS_USE_LSR
11056 +#include "lsr_cfg.h"
11057 +#else
11058 +#include "mpls_mpls_impl.h"
11059 +#endif
11061 +ldp_global *ldp_global_create(mpls_instance_handle data)
11063 + ldp_global *g = (ldp_global *) mpls_malloc(sizeof(ldp_global));
11065 + if (g) {
11066 + memset(g, 0, sizeof(ldp_global));
11068 + LDP_ENTER(g->user_data, "ldp_global_create");
11070 + g->global_lock = mpls_lock_create("_ldp_global_lock_");
11071 + mpls_lock_get(g->global_lock);
11073 + MPLS_LIST_INIT(&g->hop_list, ldp_hop_list);
11074 + MPLS_LIST_INIT(&g->outlabel, ldp_outlabel);
11075 + MPLS_LIST_INIT(&g->resource, ldp_resource);
11076 + MPLS_LIST_INIT(&g->inlabel, ldp_inlabel);
11077 + MPLS_LIST_INIT(&g->session, ldp_session);
11078 + MPLS_LIST_INIT(&g->nexthop, ldp_nexthop);
11079 + MPLS_LIST_INIT(&g->tunnel, ldp_tunnel);
11080 + MPLS_LIST_INIT(&g->entity, ldp_entity);
11081 + MPLS_LIST_INIT(&g->addr, ldp_addr);
11082 + MPLS_LIST_INIT(&g->attr, ldp_attr);
11083 + MPLS_LIST_INIT(&g->peer, ldp_peer);
11084 + MPLS_LIST_INIT(&g->fec, ldp_fec);
11085 + MPLS_LIST_INIT(&g->adj, ldp_adj);
11086 + MPLS_LIST_INIT(&g->iff, ldp_if);
11088 + g->message_identifier = 1;
11089 + g->configuration_sequence_number = 1;
11090 + g->lsp_control_mode = LDP_GLOBAL_DEF_CONTROL_MODE;
11091 + g->label_retention_mode = LDP_GLOBAL_DEF_RETENTION_MODE;
11092 + g->lsp_repair_mode = LDP_GLOBAL_DEF_REPAIR_MODE;
11093 + g->propagate_release = LDP_GLOBAL_DEF_PROPOGATE_RELEASE;
11094 + g->label_merge = LDP_GLOBAL_DEF_LABEL_MERGE;
11095 + g->loop_detection_mode = LDP_GLOBAL_DEF_LOOP_DETECTION_MODE;
11096 + g->ttl_less_domain = LDP_GLOBAL_DEF_TTLLESS_DOMAIN;
11097 + g->local_tcp_port = LDP_GLOBAL_DEF_LOCAL_TCP_PORT;
11098 + g->local_udp_port = LDP_GLOBAL_DEF_LOCAL_UDP_PORT;
11099 + g->send_address_messages = LDP_GLOBAL_DEF_SEND_ADDR_MSG;
11100 + g->backoff_step = LDP_GLOBAL_DEF_BACKOFF_STEP;
11101 + g->send_lsrid_mapping = LDP_GLOBAL_DEF_SEND_LSRID_MAPPING;
11102 + g->no_route_to_peer_time = LDP_GLOBAL_DEF_NO_ROUTE_RETRY_TIME;
11104 + g->keepalive_timer = LDP_ENTITY_DEF_KEEPALIVE_TIMER;
11105 + g->keepalive_interval = LDP_ENTITY_DEF_KEEPALIVE_INTERVAL;
11106 + g->hellotime_timer = LDP_ENTITY_DEF_HELLOTIME_TIMER;
11107 + g->hellotime_interval = LDP_ENTITY_DEF_HELLOTIME_INTERVAL;
11109 + g->admin_state = MPLS_ADMIN_DISABLE;
11110 + g->user_data = data;
11112 + g->addr_tree = mpls_tree_create(32);
11113 + g->fec_tree = mpls_tree_create(32);
11115 + mpls_lock_release(g->global_lock);
11117 + LDP_EXIT(g->user_data, "ldp_global_create");
11120 + return g;
11123 +mpls_return_enum ldp_global_startup(ldp_global * g)
11125 + ldp_entity *e = NULL;
11126 + mpls_dest dest;
11128 + MPLS_ASSERT(g != NULL);
11130 + LDP_ENTER(g->user_data, "ldp_global_startup");
11132 + if (g->lsr_identifier.type == MPLS_FAMILY_NONE) {
11133 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ERROR,
11134 + "ldp_global_startup: invalid LSRID\n");
11135 + goto ldp_global_startup_cleanup;
11138 + g->timer_handle = mpls_timer_open(g->user_data);
11139 + if (mpls_timer_mgr_handle_verify(g->timer_handle) == MPLS_BOOL_FALSE) {
11140 + goto ldp_global_startup_cleanup;
11143 + g->socket_handle = mpls_socket_mgr_open(g->user_data);
11144 + if (mpls_socket_mgr_handle_verify(g->socket_handle) == MPLS_BOOL_FALSE) {
11145 + goto ldp_global_startup_cleanup;
11148 + g->ifmgr_handle = mpls_ifmgr_open(g->user_data, g);
11149 + if (mpls_ifmgr_handle_verify(g->ifmgr_handle) == MPLS_BOOL_FALSE) {
11150 + goto ldp_global_startup_cleanup;
11153 + g->fib_handle = mpls_fib_open(g->user_data, g);
11154 + if (mpls_fib_handle_verify(g->fib_handle) == MPLS_BOOL_FALSE) {
11155 + goto ldp_global_startup_cleanup;
11158 +#if MPLS_USE_LSR
11159 + if (!g->lsr_handle) {
11160 + goto ldp_global_startup_cleanup;
11162 +#else
11163 + g->mpls_handle = mpls_mpls_open(g->user_data);
11164 + if (mpls_mpls_handle_verify(g->mpls_handle) == MPLS_BOOL_FALSE) {
11165 + goto ldp_global_startup_cleanup;
11167 +#endif
11169 + g->hello_socket = mpls_socket_create_udp(g->socket_handle);
11170 + if (mpls_socket_handle_verify(g->socket_handle, g->hello_socket) == MPLS_BOOL_FALSE) {
11171 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
11172 + "ldp_global_startup: error creating UDP socket\n");
11173 + goto ldp_global_startup_cleanup;
11176 + dest.addr.type = MPLS_FAMILY_IPV4;
11177 + dest.port = g->local_udp_port;
11178 + dest.addr.u.ipv4 = INADDR_ANY;
11179 + // dest.addr.u.ipv4 = INADDR_ALLRTRS_GROUP;
11181 + if (mpls_socket_bind(g->socket_handle, g->hello_socket, &dest) == MPLS_FAILURE) {
11182 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
11183 + "ldp_global_startup: error binding UDP socket\n");
11184 + goto ldp_global_startup_cleanup;
11187 + if (mpls_socket_options(g->socket_handle, g->hello_socket,
11188 + MPLS_SOCKOP_NONBLOCK | MPLS_SOCKOP_REUSE) == MPLS_FAILURE) {
11189 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
11190 + "ldp_global_startup: error setting UDP socket options\n");
11191 + goto ldp_global_startup_cleanup;
11193 + if (mpls_socket_multicast_options(g->socket_handle, g->hello_socket, 1, 0) ==
11194 + MPLS_FAILURE) {
11195 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
11196 + "ldp_global_startup: error setting UDP socket multicast options\n");
11197 + goto ldp_global_startup_cleanup;
11199 + mpls_socket_readlist_add(g->socket_handle, g->hello_socket, 0, MPLS_SOCKET_UDP_DATA);
11201 + g->listen_socket = mpls_socket_create_tcp(g->socket_handle);
11202 + if (mpls_socket_handle_verify(g->socket_handle, g->listen_socket) == MPLS_BOOL_FALSE) {
11203 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
11204 + "ldp_global_startup: error creating TCP socket\n");
11205 + goto ldp_global_startup_cleanup;
11207 + if (mpls_socket_options(g->socket_handle, g->listen_socket,
11208 + MPLS_SOCKOP_NONBLOCK | MPLS_SOCKOP_REUSE) == MPLS_FAILURE) {
11209 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
11210 + "ldp_global_startup: error setting TCP socket options\n");
11211 + goto ldp_global_startup_cleanup;
11214 + dest.addr.type = MPLS_FAMILY_IPV4;
11215 + dest.port = g->local_tcp_port;
11216 + dest.addr.u.ipv4 = INADDR_ANY;
11218 + if (mpls_socket_bind(g->socket_handle, g->listen_socket, &dest) == MPLS_FAILURE) {
11219 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
11220 + "ldp_global_startup: error binding TCP socket\n");
11221 + goto ldp_global_startup_cleanup;
11224 + if (mpls_socket_tcp_listen(g->socket_handle, g->listen_socket, 15) ==
11225 + MPLS_FAILURE) {
11226 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
11227 + "ldp_global_startup: error setting listen buffer for TCP socket\n");
11228 + goto ldp_global_startup_cleanup;
11231 + mpls_socket_readlist_add(g->socket_handle, g->listen_socket, 0,
11232 + MPLS_SOCKET_TCP_LISTEN);
11234 + g->admin_state = MPLS_ADMIN_ENABLE;
11236 + e = MPLS_LIST_HEAD(&g->entity);
11237 + while (e != NULL) {
11238 + ldp_entity_startup(g, e);
11239 + e = MPLS_LIST_NEXT(&g->entity, e, _global);
11242 + LDP_EXIT(g->user_data, "ldp_global_startup");
11243 + return MPLS_SUCCESS;
11245 +ldp_global_startup_cleanup:
11246 + ldp_global_shutdown(g);
11247 + mpls_socket_close(g->socket_handle, g->hello_socket);
11248 + mpls_socket_close(g->socket_handle, g->listen_socket);
11249 + g->hello_socket = 0;
11250 + g->listen_socket = 0;
11252 + LDP_EXIT(g->user_data, "ldp_global_startup-error");
11254 + return MPLS_FAILURE;
11257 +mpls_return_enum ldp_global_shutdown(ldp_global * g)
11259 + ldp_entity *e = NULL;
11260 + ldp_nexthop *n;
11261 + ldp_fec *f;
11262 + ldp_addr *a;
11263 + ldp_if *i;
11265 + MPLS_ASSERT(g);
11267 + LDP_ENTER(g->user_data, "ldp_global_shutdown");
11269 + e = MPLS_LIST_HEAD(&g->entity);
11270 + while (e != NULL) {
11271 + ldp_entity_shutdown(g, e, 1);
11272 + e = MPLS_LIST_NEXT(&g->entity, e, _global);
11275 + g->admin_state = MPLS_ADMIN_DISABLE;
11277 + mpls_socket_readlist_del(g->socket_handle, g->hello_socket);
11278 + mpls_socket_close(g->socket_handle, g->hello_socket);
11280 + mpls_socket_readlist_del(g->socket_handle, g->listen_socket);
11281 + mpls_socket_close(g->socket_handle, g->listen_socket);
11283 + mpls_lock_release(g->global_lock);
11284 + mpls_timer_close(g->timer_handle);
11285 + mpls_lock_get(g->global_lock);
11287 + mpls_socket_mgr_close(g->socket_handle);
11288 + mpls_ifmgr_close(g->ifmgr_handle);
11289 + mpls_fib_close(g->fib_handle);
11291 +#if MPLS_USE_LSR
11292 +#else
11293 + mpls_mpls_close(g->mpls_handle);
11294 +#endif
11296 + LDP_EXIT(g->user_data, "ldp_global_shutdown");
11298 + return MPLS_SUCCESS;
11301 +mpls_return_enum ldp_global_delete(ldp_global * g)
11303 + ldp_fec *fp;
11304 + ldp_fec *nfp;
11305 + ldp_if *ifp;
11306 + ldp_if *nifp;
11307 + ldp_addr *ap;
11308 + ldp_addr *nap;
11309 + ldp_nexthop *nhp;
11310 + ldp_nexthop *nnhp;
11311 + ldp_attr *atp;
11312 + ldp_attr *natp;
11313 + ldp_inlabel *inp;
11314 + ldp_inlabel *ninp;
11315 + ldp_outlabel *outp;
11316 + ldp_outlabel *noutp;
11317 + ldp_entity *ep;
11318 + ldp_entity *nep;
11320 + if (g) {
11321 + /* clean up the entities that were configured, sessions and adj should
11322 + * already have been cleaned up when the entity was shutdown
11323 + */
11324 + ep = MPLS_LIST_HEAD(&g->entity);
11325 + while (ep != NULL) {
11326 + nep = MPLS_LIST_NEXT(&g->entity, ep, _global);
11327 + switch (ep->entity_type) {
11328 + case LDP_DIRECT:
11329 + ldp_entity_del_if(g,ep);
11330 + break;
11331 + case LDP_INDIRECT:
11332 + ldp_entity_del_peer(ep);
11333 + break;
11334 + default:
11335 + MPLS_ASSERT(0);
11337 + _ldp_global_del_entity(g, ep);
11338 + ep = nep;
11341 + /* need to properly purge FECs/nexthops/interfaces/addresses */
11343 + fp = MPLS_LIST_HEAD(&g->fec);
11344 + while (fp != NULL) {
11345 + nfp = MPLS_LIST_NEXT(&g->fec, fp, _global);
11347 + nhp = MPLS_LIST_HEAD(&fp->nh_root);
11348 + while (nhp) {
11349 + nnhp = MPLS_LIST_NEXT(&fp->nh_root, nhp, _fec);
11350 + ldp_fec_del_nexthop(g, fp, nhp);
11351 + nhp = nnhp;
11353 + MPLS_REFCNT_RELEASE2(g, fp, ldp_fec_delete);
11355 + fp = nfp;
11358 + ifp = MPLS_LIST_HEAD(&g->iff);
11359 + while (ifp != NULL) {
11360 + nifp = MPLS_LIST_NEXT(&g->iff, ifp, _global);
11362 + ap = MPLS_LIST_HEAD(&ifp->addr_root);
11363 + while (ap != NULL) {
11364 + nap = MPLS_LIST_NEXT(&ifp->addr_root, ap, _if);
11365 + ldp_if_del_addr(g, ifp, ap);
11366 + ap = nap;
11368 + MPLS_REFCNT_RELEASE2(g, ifp, ldp_if_delete);
11370 + ifp = nifp;
11373 + nhp = MPLS_LIST_HEAD(&g->nexthop);
11374 + while (nhp != NULL) {
11375 + LDP_PRINT(g->user_data,"Left over NH: %p type %d ref %d",
11376 + nhp, nhp->info.type, nhp->_refcnt);
11377 + switch(nhp->info.type) {
11378 + case MPLS_NH_IP:
11379 + LDP_PRINT(g->user_data," IP %08x addr %p",
11380 + nhp->info.ip.u.ipv4, nhp->addr);
11381 + break;
11382 + case MPLS_NH_IF:
11383 + LDP_PRINT(g->user_data," IF %s handle %p",
11384 + nhp->info.if_handle->name, nhp->iff);
11385 + break;
11386 + case MPLS_NH_OUTSEGMENT:
11387 + LDP_PRINT(g->user_data," OS %p", nhp->outlabel);
11388 + break;
11389 + default:
11390 + LDP_PRINT(g->user_data," EMPTY");
11391 + break;
11393 + nnhp = MPLS_LIST_NEXT(&g->nexthop, nhp, _global);
11394 +// _ldp_global_del_nexthop(g, nhp);
11395 + nhp = nnhp;
11398 + ap = MPLS_LIST_HEAD(&g->addr);
11399 + while (ap != NULL) {
11400 + LDP_PRINT(g->user_data, "Left over ADDR: %p address %08x",
11401 + ap, ap->address.u.ipv4);
11402 + nap = MPLS_LIST_NEXT(&g->addr, ap, _global);
11403 +// _ldp_global_del_addr(g, ap);
11404 + ap = nap;
11407 + atp = MPLS_LIST_HEAD(&g->attr);
11408 + while (atp != NULL) {
11409 + LDP_PRINT(g->user_data, "Left over ATTR: %p %d", atp, atp->_refcnt);
11410 + natp = MPLS_LIST_NEXT(&g->attr, atp, _global);
11411 +// _ldp_global_del_attr(g, atp);
11412 + atp = natp;
11415 + inp = MPLS_LIST_HEAD(&g->inlabel);
11416 + while (inp != NULL) {
11417 + LDP_PRINT(g->user_data,"Left over INLABEL: %p %d", inp, inp->_refcnt);
11418 + ninp = MPLS_LIST_NEXT(&g->inlabel, inp, _global);
11419 + inp = ninp;
11422 + outp = MPLS_LIST_HEAD(&g->outlabel);
11423 + while (outp != NULL) {
11424 + LDP_PRINT(g->user_data, "Left over OUTLABEL: %p %d", outp, outp->_refcnt);
11425 + noutp = MPLS_LIST_NEXT(&g->outlabel, outp, _global);
11426 + outp = noutp;
11429 + mpls_tree_delete(g->addr_tree);
11430 + mpls_tree_delete(g->fec_tree);
11432 + mpls_lock_delete(g->global_lock);
11433 + LDP_PRINT(g->user_data, "global delete");
11434 + mpls_free(g);
11436 + return MPLS_SUCCESS;
11439 +void _ldp_global_add_attr(ldp_global * g, ldp_attr * a)
11441 + ldp_attr *ap = NULL;
11443 + MPLS_ASSERT(g && a);
11444 + ap = MPLS_LIST_HEAD(&g->attr);
11445 + while (ap != NULL) {
11446 + if (ap->index > a->index) {
11447 + MPLS_LIST_INSERT_BEFORE(&g->attr, ap, a, _global);
11448 + return;
11450 + ap = MPLS_LIST_NEXT(&g->attr, ap, _global);
11452 + MPLS_LIST_ADD_TAIL(&g->attr, a, _global, ldp_attr);
11455 +void _ldp_global_del_attr(ldp_global * g, ldp_attr * a)
11457 + MPLS_ASSERT(g && a);
11458 + MPLS_LIST_REMOVE(&g->attr, a, _global);
11461 +void _ldp_global_add_peer(ldp_global * g, ldp_peer * p)
11463 + ldp_peer *pp = NULL;
11465 + MPLS_ASSERT(g && p);
11466 + MPLS_REFCNT_HOLD(p);
11467 + pp = MPLS_LIST_HEAD(&g->peer);
11468 + while (pp != NULL) {
11469 + if (pp->index > p->index) {
11470 + MPLS_LIST_INSERT_BEFORE(&g->peer, pp, p, _global);
11471 + return;
11473 + pp = MPLS_LIST_NEXT(&g->peer, pp, _global);
11475 + MPLS_LIST_ADD_TAIL(&g->peer, p, _global, ldp_peer);
11478 +void _ldp_global_del_peer(ldp_global * g, ldp_peer * p)
11480 + MPLS_ASSERT(g && p);
11481 + MPLS_LIST_REMOVE(&g->peer, p, _global);
11482 + MPLS_REFCNT_RELEASE(p, ldp_peer_delete);
11486 + * _ldp_global_add_if/del_if and _ldp_global_add_addr/del_addr are
11487 + * not the same as the rest of the global_add/del functions. They
11488 + * do not hold refcnts, they are used as part of the create and delete
11489 + * process of these structures
11490 + */
11492 +void _ldp_global_add_if(ldp_global * g, ldp_if * i)
11494 + ldp_if *ip = NULL;
11496 + MPLS_ASSERT(g && i);
11497 + ip = MPLS_LIST_HEAD(&g->iff);
11498 + while (ip != NULL) {
11499 + if (ip->index > i->index) {
11500 + MPLS_LIST_INSERT_BEFORE(&g->iff, ip, i, _global);
11501 + return;
11503 + ip = MPLS_LIST_NEXT(&g->iff, ip, _global);
11505 + MPLS_LIST_ADD_TAIL(&g->iff, i, _global, ldp_if);
11508 +void _ldp_global_del_if(ldp_global * g, ldp_if * i)
11510 + MPLS_ASSERT(g && i);
11511 + MPLS_LIST_REMOVE(&g->iff, i, _global);
11514 +void _ldp_global_add_addr(ldp_global * g, ldp_addr * a)
11516 + ldp_addr *ap = NULL;
11518 + MPLS_ASSERT(g && a);
11519 + ap = MPLS_LIST_HEAD(&g->addr);
11520 + while (ap != NULL) {
11521 + if (ap->index > a->index) {
11522 + MPLS_LIST_INSERT_BEFORE(&g->addr, ap, a, _global);
11523 + return;
11525 + ap = MPLS_LIST_NEXT(&g->addr, ap, _global);
11527 + MPLS_LIST_ADD_TAIL(&g->addr, a, _global, ldp_addr);
11530 +void _ldp_global_del_addr(ldp_global * g, ldp_addr * a)
11532 + MPLS_ASSERT(g && a);
11533 + MPLS_LIST_REMOVE(&g->addr, a, _global);
11536 +void _ldp_global_add_adj(ldp_global * g, ldp_adj * a)
11538 + ldp_adj *ap = NULL;
11540 + MPLS_ASSERT(g && a);
11541 + MPLS_REFCNT_HOLD(a);
11542 + ap = MPLS_LIST_HEAD(&g->adj);
11543 + while (ap != NULL) {
11544 + if (ap->index > a->index) {
11545 + MPLS_LIST_INSERT_BEFORE(&g->adj, ap, a, _global);
11546 + return;
11548 + ap = MPLS_LIST_NEXT(&g->adj, ap, _global);
11550 + MPLS_LIST_ADD_TAIL(&g->adj, a, _global, ldp_adj);
11553 +void _ldp_global_del_adj(ldp_global * g, ldp_adj * a)
11555 + MPLS_ASSERT(g && a);
11556 + MPLS_LIST_REMOVE(&g->adj, a, _global);
11557 + MPLS_REFCNT_RELEASE(a, ldp_adj_delete);
11560 +void _ldp_global_add_entity(ldp_global * g, ldp_entity * e)
11562 + ldp_entity *ep = NULL;
11564 + MPLS_ASSERT(g && e);
11565 + MPLS_REFCNT_HOLD(e);
11566 + ep = MPLS_LIST_HEAD(&g->entity);
11567 + while (ep != NULL) {
11568 + if (ep->index > e->index) {
11569 + MPLS_LIST_INSERT_BEFORE(&g->entity, ep, e, _global);
11570 + return;
11572 + ep = MPLS_LIST_NEXT(&g->entity, ep, _global);
11574 + MPLS_LIST_ADD_TAIL(&g->entity, e, _global, ldp_entity);
11577 +void _ldp_global_del_entity(ldp_global * g, ldp_entity * e)
11579 + MPLS_ASSERT(g && e);
11580 + MPLS_LIST_REMOVE(&g->entity, e, _global);
11581 + MPLS_REFCNT_RELEASE(e, ldp_entity_delete);
11584 +void _ldp_global_add_session(ldp_global * g, ldp_session * s)
11586 + ldp_session *sp = NULL;
11588 + MPLS_ASSERT(g && s);
11589 + MPLS_REFCNT_HOLD(s);
11590 + s->on_global = MPLS_BOOL_TRUE;
11591 + sp = MPLS_LIST_HEAD(&g->session);
11592 + while (sp != NULL) {
11593 + if (sp->index > s->index) {
11594 + MPLS_LIST_INSERT_BEFORE(&g->session, sp, s, _global);
11595 + return;
11597 + sp = MPLS_LIST_NEXT(&g->session, sp, _global);
11599 + MPLS_LIST_ADD_TAIL(&g->session, s, _global, ldp_session);
11602 +void _ldp_global_del_session(ldp_global * g, ldp_session * s)
11604 + MPLS_ASSERT(g && s);
11605 + MPLS_ASSERT(s->on_global == MPLS_BOOL_TRUE);
11606 + MPLS_LIST_REMOVE(&g->session, s, _global);
11607 + s->on_global = MPLS_BOOL_FALSE;
11608 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
11611 +mpls_return_enum _ldp_global_add_inlabel(ldp_global * g, ldp_inlabel * i)
11613 + ldp_inlabel *ip = NULL;
11614 + mpls_return_enum result;
11616 + MPLS_ASSERT(g && i);
11618 +#if MPLS_USE_LSR
11620 + lsr_insegment iseg;
11621 + memcpy(&iseg.info,&i->info,sizeof(mpls_insegment));
11622 + result = lsr_cfg_insegment_set(g->lsr_handle, &iseg, LSR_CFG_ADD|
11623 + LSR_INSEGMENT_CFG_NPOP|LSR_INSEGMENT_CFG_FAMILY|
11624 + LSR_INSEGMENT_CFG_LABELSPACE|LSR_INSEGMENT_CFG_LABEL|
11625 + LSR_INSEGMENT_CFG_OWNER);
11626 + memcpy(&i->info, &iseg.info, sizeof(mpls_insegment));
11627 + i->info.handle = iseg.index;
11629 +#else
11630 + result = mpls_mpls_insegment_add(g->mpls_handle, &i->info);
11631 +#endif
11632 + if (result != MPLS_SUCCESS) {
11633 + return result;
11636 + ip = MPLS_LIST_HEAD(&g->inlabel);
11637 + while (ip != NULL) {
11638 + if (ip->index > i->index) {
11639 + MPLS_LIST_INSERT_BEFORE(&g->inlabel, ip, i, _global);
11640 + return MPLS_SUCCESS;
11642 + ip = MPLS_LIST_NEXT(&g->inlabel, ip, _global);
11644 + MPLS_LIST_ADD_TAIL(&g->inlabel, i, _global, ldp_inlabel);
11645 + return MPLS_SUCCESS;
11648 +mpls_return_enum _ldp_global_del_inlabel(ldp_global * g, ldp_inlabel * i)
11650 + MPLS_ASSERT(g && i);
11651 + MPLS_ASSERT(i->reuse_count == 0);
11652 +#if MPLS_USE_LSR
11654 + lsr_insegment iseg;
11655 + iseg.index = i->info.handle;
11656 + lsr_cfg_insegment_set(g->lsr_handle, &iseg, LSR_CFG_DEL);
11658 +#else
11659 + mpls_mpls_insegment_del(g->mpls_handle, &i->info);
11660 +#endif
11661 + MPLS_LIST_REMOVE(&g->inlabel, i, _global);
11662 + return MPLS_SUCCESS;
11665 +mpls_return_enum _ldp_global_add_outlabel(ldp_global * g, ldp_outlabel * o)
11667 + ldp_outlabel *op = NULL;
11668 + mpls_return_enum result;
11670 + MPLS_ASSERT(g && o);
11671 +#if MPLS_USE_LSR
11673 + lsr_outsegment oseg;
11674 + memcpy(&oseg.info, &o->info, sizeof(mpls_outsegment));
11675 + result = lsr_cfg_outsegment_set(g->lsr_handle, &oseg, LSR_CFG_ADD|
11676 + LSR_OUTSEGMENT_CFG_PUSH_LABEL|LSR_OUTSEGMENT_CFG_OWNER|
11677 + LSR_OUTSEGMENT_CFG_INTERFACE|LSR_OUTSEGMENT_CFG_LABEL|
11678 + LSR_OUTSEGMENT_CFG_NEXTHOP);
11679 + o->info.handle = oseg.index;
11681 +#else
11682 + result = mpls_mpls_outsegment_add(g->mpls_handle, &o->info);
11683 +#endif
11685 + if (result != MPLS_SUCCESS) {
11686 + return result;
11689 + o->switching = MPLS_BOOL_TRUE;
11690 + op = MPLS_LIST_HEAD(&g->outlabel);
11691 + while (op != NULL) {
11692 + if (op->index > o->index) {
11693 + MPLS_LIST_INSERT_BEFORE(&g->outlabel, op, o, _global);
11694 + return MPLS_SUCCESS;
11696 + op = MPLS_LIST_NEXT(&g->outlabel, op, _global);
11698 + MPLS_LIST_ADD_TAIL(&g->outlabel, o, _global, ldp_outlabel);
11699 + return MPLS_SUCCESS;
11702 +mpls_return_enum _ldp_global_del_outlabel(ldp_global * g, ldp_outlabel * o)
11704 + MPLS_ASSERT(g && o);
11705 +#if MPLS_USE_LSR
11707 + lsr_outsegment oseg;
11708 + oseg.index = o->info.handle;
11709 + lsr_cfg_outsegment_set(g->lsr_handle, &oseg, LSR_CFG_DEL);
11711 +#else
11712 +LDP_PRINT(g->user_data,"Here 1");
11713 + mpls_mpls_outsegment_del(g->mpls_handle, &o->info);
11714 +#endif
11716 +LDP_PRINT(g->user_data,"Here 2");
11717 + o->switching = MPLS_BOOL_FALSE;
11718 +LDP_PRINT(g->user_data,"Here 3");
11719 + MPLS_ASSERT(o->merge_count == 0);
11720 +LDP_PRINT(g->user_data,"Here 4");
11721 + MPLS_LIST_REMOVE(&g->outlabel, o, _global);
11722 +LDP_PRINT(g->user_data,"Here 5");
11723 + return MPLS_SUCCESS;
11726 +mpls_return_enum ldp_global_find_attr_index(ldp_global * g, uint32_t index,
11727 + ldp_attr ** attr)
11729 + ldp_attr *a = NULL;
11731 + if (g && index > 0) {
11733 + /* because we sort our inserts by index, this lets us know
11734 + if we've "walked" past the end of the list */
11736 + a = MPLS_LIST_TAIL(&g->attr);
11737 + if (a == NULL || a->index < index) {
11738 + return MPLS_END_OF_LIST;
11739 + *attr = NULL;
11742 + a = MPLS_LIST_HEAD(&g->attr);
11743 + while (a != NULL) {
11744 + if (a->index == index) {
11745 + *attr = a;
11746 + return MPLS_SUCCESS;
11748 + a = MPLS_LIST_NEXT(&g->attr, a, _global);
11751 + *attr = NULL;
11752 + return MPLS_FAILURE;
11755 +mpls_return_enum ldp_global_find_session_index(ldp_global * g, uint32_t index,
11756 + ldp_session ** session)
11758 + ldp_session *s = NULL;
11760 + if (g && index > 0) {
11762 + /* because we sort our inserts by index, this lets us know
11763 + if we've "walked" past the end of the list */
11765 + s = MPLS_LIST_TAIL(&g->session);
11766 + if (s == NULL || s->index < index) {
11767 + *session = NULL;
11768 + return MPLS_END_OF_LIST;
11771 + s = MPLS_LIST_HEAD(&g->session);
11772 + while (s != NULL) {
11773 + if (s->index == index) {
11774 + *session = s;
11775 + return MPLS_SUCCESS;
11777 + s = MPLS_LIST_NEXT(&g->session, s, _global);
11780 + *session = NULL;
11781 + return MPLS_FAILURE;
11784 +mpls_return_enum ldp_global_find_inlabel_index(ldp_global * g, uint32_t index,
11785 + ldp_inlabel ** inlabel)
11787 + ldp_inlabel *i = NULL;
11789 + if (g && index > 0) {
11791 + /* because we sort our inserts by index, this lets us know
11792 + if we've "walked" past the end of the list */
11794 + i = MPLS_LIST_TAIL(&g->inlabel);
11795 + if (i == NULL || i->index < index) {
11796 + *inlabel = NULL;
11797 + return MPLS_END_OF_LIST;
11800 + i = MPLS_LIST_HEAD(&g->inlabel);
11801 + while (i != NULL) {
11802 + if (i->index == index) {
11803 + *inlabel = i;
11804 + return MPLS_SUCCESS;
11806 + i = MPLS_LIST_NEXT(&g->inlabel, i, _global);
11809 + *inlabel = NULL;
11810 + return MPLS_FAILURE;
11813 +mpls_return_enum ldp_global_find_outlabel_index(ldp_global * g, uint32_t index,
11814 + ldp_outlabel ** outlabel)
11816 + ldp_outlabel *o = NULL;
11818 + if (g && index > 0) {
11820 + /* because we sort our inserts by index, this lets us know
11821 + if we've "walked" past the end of the list */
11823 + o = MPLS_LIST_TAIL(&g->outlabel);
11824 + if (o == NULL || o->index < index) {
11825 + *outlabel = NULL;
11826 + return MPLS_END_OF_LIST;
11829 + o = MPLS_LIST_HEAD(&g->outlabel);
11830 + while (o != NULL) {
11831 + if (o->index == index) {
11832 + *outlabel = o;
11833 + return MPLS_SUCCESS;
11835 + o = MPLS_LIST_NEXT(&g->outlabel, o, _global);
11838 + *outlabel = NULL;
11839 + return MPLS_FAILURE;
11842 +ldp_outlabel *ldp_global_find_outlabel_handle(ldp_global * g,
11843 + mpls_outsegment_handle handle)
11845 + ldp_outlabel *o = MPLS_LIST_HEAD(&g->outlabel);
11847 + if (g) {
11848 + while (o != NULL) {
11849 + if (!mpls_outsegment_handle_compare(o->info.handle, handle))
11850 + return o;
11852 + o = MPLS_LIST_NEXT(&g->outlabel, o, _global);
11855 + return NULL;
11858 +mpls_return_enum ldp_global_find_entity_index(ldp_global * g, uint32_t index,
11859 + ldp_entity ** entity)
11861 + ldp_entity *e = NULL;
11863 + if (g && index > 0) {
11865 + /* because we sort our inserts by index, this lets us know
11866 + if we've "walked" past the end of the list */
11868 + e = MPLS_LIST_TAIL(&g->entity);
11869 + if (e == NULL || e->index < index) {
11870 + *entity = NULL;
11871 + return MPLS_END_OF_LIST;
11874 + e = MPLS_LIST_HEAD(&g->entity);
11875 + while (e != NULL) {
11876 + if (e->index == index) {
11877 + *entity = e;
11878 + return MPLS_SUCCESS;
11880 + e = MPLS_LIST_NEXT(&g->entity, e, _global);
11883 + *entity = NULL;
11884 + return MPLS_FAILURE;
11887 +ldp_peer *ldp_global_find_peer_addr(ldp_global * g, mpls_inet_addr * addr)
11889 + ldp_peer *p;
11891 + MPLS_ASSERT(g && addr);
11893 + /* JLEU: we will need to add a tree to optimize this search,
11894 + known peers will be in tree, unknown will take a "slow path" to
11895 + verify them, then be added to tree */
11897 + p = MPLS_LIST_HEAD(&g->peer);
11898 + while (p) {
11899 + LDP_PRINT(g->user_data,
11900 + "ldp_global_find_peer_lsrid: peer: %08x lsrid: %08x\n",
11901 + p->dest.addr.u.ipv4, addr->u.ipv4);
11902 + if (!mpls_inet_addr_compare(&p->dest.addr, addr)) {
11903 + return p;
11905 + p = MPLS_LIST_NEXT(&g->peer, p, _global);
11907 + return NULL;
11910 +mpls_return_enum ldp_global_find_adj_index(ldp_global * g, uint32_t index,
11911 + ldp_adj ** adj)
11913 + ldp_adj *a = NULL;
11915 + if (g && index > 0) {
11916 + /* because we sort our inserts by index, this lets us know
11917 + if we've "walked" past the end of the list */
11919 + a = MPLS_LIST_TAIL(&g->adj);
11920 + if (a == NULL || a->index < index) {
11921 + return MPLS_END_OF_LIST;
11922 + *adj = NULL;
11925 + a = MPLS_LIST_HEAD(&g->adj);
11926 + while (a != NULL) {
11927 + if (a->index == index) {
11928 + *adj = a;
11929 + return MPLS_SUCCESS;
11931 + a = MPLS_LIST_NEXT(&g->adj, a, _global);
11934 + *adj = NULL;
11935 + return MPLS_FAILURE;
11938 +mpls_return_enum ldp_global_find_peer_index(ldp_global * g, uint32_t index,
11939 + ldp_peer ** peer)
11941 + ldp_peer *p = NULL;
11943 + if (g && index > 0) {
11944 + /* because we sort our inserts by index, this lets us know
11945 + if we've "walked" past the end of the list */
11947 + p = MPLS_LIST_TAIL(&g->peer);
11948 + if (p == NULL || p->index < index) {
11949 + *peer = NULL;
11950 + return MPLS_END_OF_LIST;
11953 + p = MPLS_LIST_HEAD(&g->peer);
11954 + while (p != NULL) {
11955 + if (p->index == index) {
11956 + *peer = p;
11957 + return MPLS_SUCCESS;
11959 + p = MPLS_LIST_NEXT(&g->peer, p, _global);
11962 + *peer = NULL;
11963 + return MPLS_FAILURE;
11966 +mpls_return_enum ldp_global_find_fec_index(ldp_global * g, uint32_t index,
11967 + ldp_fec ** fec)
11969 + ldp_fec *f = NULL;
11971 + if (g && index > 0) {
11972 + /* because we sort our inserts by index, this lets us know
11973 + if we've "walked" past the end of the list */
11975 + f = MPLS_LIST_TAIL(&g->fec);
11976 + if (f == NULL || f->index < index) {
11977 + *fec = NULL;
11978 + return MPLS_END_OF_LIST;
11981 + f = MPLS_LIST_HEAD(&g->fec);
11982 + while (f != NULL) {
11983 + if (f->index == index) {
11984 + *fec = f;
11985 + return MPLS_SUCCESS;
11987 + f = MPLS_LIST_NEXT(&g->fec, f, _global);
11990 + *fec = NULL;
11991 + return MPLS_FAILURE;
11994 +mpls_return_enum ldp_global_find_fec(ldp_global * g, mpls_fec * m,
11995 + ldp_fec ** fec)
11997 + ldp_fec *f = NULL;
11999 + MPLS_ASSERT(g && m);
12001 + f = MPLS_LIST_HEAD(&g->fec);
12002 + do {
12003 + if (!mpls_fec_compare(m, &f->info)) {
12004 + *fec = f;
12005 + return MPLS_SUCCESS;
12007 + } while((f = MPLS_LIST_NEXT(&g->fec, f, _global)));
12008 + *fec = NULL;
12009 + return MPLS_FAILURE;
12012 +mpls_return_enum ldp_global_find_addr_index(ldp_global * g, uint32_t index,
12013 + ldp_addr ** addr)
12015 + ldp_addr *a = NULL;
12017 + if (g && index > 0) {
12019 + /* because we sort our inserts by index, this lets us know
12020 + if we've "walked" past the end of the list */
12022 + a = MPLS_LIST_TAIL(&g->addr);
12023 + if (a == NULL || a->index < index) {
12024 + *addr = NULL;
12025 + return MPLS_END_OF_LIST;
12028 + a = MPLS_LIST_HEAD(&g->addr);
12029 + while (a != NULL) {
12030 + if (a->index == index) {
12031 + *addr = a;
12032 + return MPLS_SUCCESS;
12034 + a = MPLS_LIST_NEXT(&g->addr, a, _global);
12037 + *addr = NULL;
12038 + return MPLS_FAILURE;
12041 +mpls_return_enum ldp_global_find_if_index(ldp_global * g, uint32_t index,
12042 + ldp_if ** iff)
12044 + ldp_if *i = NULL;
12046 + if (g && index > 0) {
12048 + /* because we sort our inserts by index, this lets us know
12049 + if we've "walked" past the end of the list */
12051 + i = MPLS_LIST_TAIL(&g->iff);
12052 + if (i == NULL || i->index < index) {
12053 + *iff = NULL;
12054 + return MPLS_END_OF_LIST;
12057 + i = MPLS_LIST_HEAD(&g->iff);
12058 + while (i != NULL) {
12059 + if (i->index == index) {
12060 + *iff = i;
12061 + return MPLS_SUCCESS;
12063 + i = MPLS_LIST_NEXT(&g->iff, i, _global);
12066 + *iff = NULL;
12067 + return MPLS_FAILURE;
12070 +ldp_if *ldp_global_find_if_handle(ldp_global * g, mpls_if_handle handle)
12072 + ldp_if *i = MPLS_LIST_HEAD(&g->iff);
12074 + if (g) {
12075 + while (i != NULL) {
12076 + if (!mpls_if_handle_compare(i->handle, handle))
12077 + return i;
12079 + i = MPLS_LIST_NEXT(&g->iff, i, _global);
12082 + return NULL;
12085 +ldp_adj *ldp_global_find_adj_ldpid(ldp_global * g, mpls_inet_addr * lsraddr,
12086 + int labelspace)
12089 + ldp_adj *a = MPLS_LIST_HEAD(&g->adj);
12091 + while (a != NULL) {
12092 + if ((!mpls_inet_addr_compare(lsraddr, &a->remote_lsr_address)) &&
12093 + labelspace == a->remote_label_space)
12094 + return a;
12096 + a = MPLS_LIST_NEXT(&g->adj, a, _global);
12098 + return NULL;
12101 +mpls_return_enum ldp_global_find_tunnel_index(ldp_global * g, uint32_t index,
12102 + ldp_tunnel ** tunnel)
12104 + ldp_tunnel *t = NULL;
12106 + if (g && index > 0) {
12107 + /* because we sort our inserts by index, this lets us know
12108 + if we've "walked" past the end of the list */
12110 + t = MPLS_LIST_TAIL(&g->tunnel);
12111 + if (t == NULL || t->index < index) {
12112 + *tunnel = NULL;
12113 + return MPLS_END_OF_LIST;
12116 + t = MPLS_LIST_HEAD(&g->tunnel);
12117 + while (t != NULL) {
12118 + if (t->index == index) {
12119 + *tunnel = t;
12120 + return MPLS_SUCCESS;
12122 + t = MPLS_LIST_NEXT(&g->tunnel, t, _global);
12125 + *tunnel = NULL;
12126 + return MPLS_FAILURE;
12129 +mpls_return_enum ldp_global_find_resource_index(ldp_global * g, uint32_t index,
12130 + ldp_resource ** resource)
12132 + ldp_resource *r = NULL;
12134 + if (g && index > 0) {
12135 + /* because we sort our inserts by index, this lets us know
12136 + if we've "walked" past the end of the list */
12138 + r = MPLS_LIST_TAIL(&g->resource);
12139 + if (r == NULL || r->index < index) {
12140 + *resource = NULL;
12141 + return MPLS_END_OF_LIST;
12144 + r = MPLS_LIST_HEAD(&g->resource);
12145 + while (r != NULL) {
12146 + if (r->index == index) {
12147 + *resource = r;
12148 + return MPLS_SUCCESS;
12150 + r = MPLS_LIST_NEXT(&g->resource, r, _global);
12153 + *resource = NULL;
12154 + return MPLS_FAILURE;
12157 +mpls_return_enum ldp_global_find_hop_list_index(ldp_global * g, uint32_t index,
12158 + ldp_hop_list ** hop_list)
12160 + ldp_hop_list *h = NULL;
12162 + if (g && index > 0) {
12163 + /* because we sort our inserts by index, this lets us know
12164 + if we've "walked" past the end of the list */
12166 + h = MPLS_LIST_TAIL(&g->hop_list);
12167 + if (h == NULL || h->index < index) {
12168 + *hop_list = NULL;
12169 + return MPLS_END_OF_LIST;
12172 + h = MPLS_LIST_HEAD(&g->hop_list);
12173 + while (h != NULL) {
12174 + if (h->index == index) {
12175 + *hop_list = h;
12176 + return MPLS_SUCCESS;
12178 + h = MPLS_LIST_NEXT(&g->hop_list, h, _global);
12181 + *hop_list = NULL;
12182 + return MPLS_FAILURE;
12185 +void _ldp_global_add_tunnel(ldp_global * g, ldp_tunnel * t)
12187 + ldp_tunnel *tp = NULL;
12189 + MPLS_ASSERT(g && t);
12190 + MPLS_REFCNT_HOLD(t);
12191 + tp = MPLS_LIST_HEAD(&g->tunnel);
12192 + while (tp != NULL) {
12193 + if (tp->index > t->index) {
12194 + MPLS_LIST_INSERT_BEFORE(&g->tunnel, tp, t, _global);
12195 + return;
12197 + tp = MPLS_LIST_NEXT(&g->tunnel, tp, _global);
12199 + MPLS_LIST_ADD_TAIL(&g->tunnel, t, _global, ldp_tunnel);
12202 +void _ldp_global_del_tunnel(ldp_global * g, ldp_tunnel * t)
12204 + MPLS_ASSERT(g && t);
12205 + MPLS_LIST_REMOVE(&g->tunnel, t, _global);
12206 + MPLS_REFCNT_RELEASE(t, ldp_tunnel_delete);
12209 +void _ldp_global_add_resource(ldp_global * g, ldp_resource * r)
12211 + ldp_resource *rp = NULL;
12213 + MPLS_ASSERT(g && r);
12214 + MPLS_REFCNT_HOLD(r);
12215 + rp = MPLS_LIST_HEAD(&g->resource);
12216 + while (rp != NULL) {
12217 + if (rp->index > r->index) {
12218 + MPLS_LIST_INSERT_BEFORE(&g->resource, rp, r, _global);
12219 + return;
12221 + rp = MPLS_LIST_NEXT(&g->resource, rp, _global);
12223 + MPLS_LIST_ADD_TAIL(&g->resource, r, _global, ldp_resource);
12226 +void _ldp_global_del_resource(ldp_global * g, ldp_resource * r)
12228 + MPLS_ASSERT(g && r);
12229 + MPLS_LIST_REMOVE(&g->resource, r, _global);
12230 + MPLS_REFCNT_RELEASE(r, ldp_resource_delete);
12233 +void _ldp_global_add_hop_list(ldp_global * g, ldp_hop_list * h)
12235 + ldp_hop_list *hp = NULL;
12237 + MPLS_ASSERT(g && h);
12238 + MPLS_REFCNT_HOLD(h);
12239 + hp = MPLS_LIST_HEAD(&g->hop_list);
12240 + while (hp != NULL) {
12241 + if (hp->index > h->index) {
12242 + MPLS_LIST_INSERT_BEFORE(&g->hop_list, hp, h, _global);
12243 + return;
12245 + hp = MPLS_LIST_NEXT(&g->hop_list, hp, _global);
12247 + MPLS_LIST_ADD_TAIL(&g->hop_list, h, _global, ldp_hop_list);
12250 +void _ldp_global_del_hop_list(ldp_global * g, ldp_hop_list * h)
12252 + MPLS_ASSERT(g && h);
12253 + MPLS_LIST_REMOVE(&g->hop_list, h, _global);
12254 + MPLS_REFCNT_RELEASE(h, ldp_hop_list_delete);
12257 +void _ldp_global_add_fec(ldp_global * g, ldp_fec * f)
12259 + ldp_fec *fp = NULL;
12261 + MPLS_ASSERT(g && f);
12262 + /*
12263 + * TESTING: jleu 6/7/2004, since I want the FEC to be cleaned up
12264 + * when it no longer has a nexthop, addr, or label, the only things that
12265 + * should increment the ref are those (nh, addr, label etc), not global
12266 + * nor inserting into the tree. I also added this comment in
12267 + * ldp_fec_create()
12268 + * MPLS_REFCNT_HOLD(f);
12269 + */
12270 + fp = MPLS_LIST_HEAD(&g->fec);
12271 + while (fp != NULL) {
12272 + if (fp->index > f->index) {
12273 + MPLS_LIST_INSERT_BEFORE(&g->fec, fp, f, _global);
12274 + return;
12276 + fp = MPLS_LIST_NEXT(&g->fec, fp, _global);
12278 + MPLS_LIST_ADD_TAIL(&g->fec, f, _global, ldp_fec);
12281 +void _ldp_global_del_fec(ldp_global * g, ldp_fec * f)
12283 + MPLS_ASSERT(g && f);
12284 + MPLS_LIST_REMOVE(&g->fec, f, _global);
12287 +void _ldp_global_add_nexthop(ldp_global * g, ldp_nexthop * nh)
12289 + ldp_nexthop *nhp = NULL;
12291 + MPLS_ASSERT(g && nh);
12292 + nhp = MPLS_LIST_HEAD(&g->nexthop);
12293 + while (nhp != NULL) {
12294 + if (nhp->index > nh->index) {
12295 + MPLS_LIST_INSERT_BEFORE(&g->nexthop, nhp, nh, _global);
12296 + return;
12298 + nhp = MPLS_LIST_NEXT(&g->nexthop, nhp, _global);
12300 + MPLS_LIST_ADD_TAIL(&g->nexthop, nh, _global, ldp_nexthop);
12303 +void _ldp_global_del_nexthop(ldp_global * g, ldp_nexthop * nh)
12305 + MPLS_ASSERT(g && nh);
12306 + MPLS_LIST_REMOVE(&g->nexthop, nh, _global);
12308 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_global.h quagga-mpls/ldpd/ldp_global.h
12309 --- quagga/ldpd/ldp_global.h 1969-12-31 18:00:00.000000000 -0600
12310 +++ quagga-mpls/ldpd/ldp_global.h 2006-08-09 21:56:10.000000000 -0500
12311 @@ -0,0 +1,102 @@
12314 + * Copyright (C) James R. Leu 2000
12315 + * jleu@mindspring.com
12317 + * This software is covered under the LGPL, for more
12318 + * info check out http://www.gnu.org/copyleft/lgpl.html
12319 + */
12321 +#ifndef _LDP_GLOBAL_H_
12322 +#define _LDP_GLOBAL_H_
12324 +#include "ldp_struct.h"
12326 +extern ldp_global *ldp_global_create(mpls_instance_handle data);
12327 +extern mpls_return_enum ldp_global_delete(ldp_global * g);
12328 +extern mpls_return_enum ldp_global_startup(ldp_global * g);
12329 +extern mpls_return_enum ldp_global_shutdown(ldp_global * g);
12331 +extern ldp_peer *ldp_global_find_peer_addr(ldp_global * g,
12332 + mpls_inet_addr * addr);
12333 +extern ldp_if *ldp_global_find_if_handle(ldp_global * g, mpls_if_handle handle);
12334 +extern ldp_adj *ldp_global_find_adj_ldpid(ldp_global * g,
12335 + mpls_inet_addr * lsraddr, int labelspace);
12337 +extern mpls_return_enum ldp_global_find_adj_index(ldp_global * g, uint32_t index, ldp_adj ** adj);
12338 +extern mpls_return_enum ldp_global_find_if_index(ldp_global * g, uint32_t index,
12339 + ldp_if **);
12340 +extern mpls_return_enum ldp_global_find_addr_index(ldp_global * g,
12341 + uint32_t index, ldp_addr ** addr);
12342 +extern mpls_return_enum ldp_global_find_attr_index(ldp_global * g,
12343 + uint32_t index, ldp_attr **);
12344 +extern mpls_return_enum ldp_global_find_session_index(ldp_global * g,
12345 + uint32_t index, ldp_session **);
12346 +extern mpls_return_enum ldp_global_find_peer_index(ldp_global * g,
12347 + uint32_t index, ldp_peer ** peer);
12348 +extern mpls_return_enum ldp_global_find_entity_index(ldp_global * g,
12349 + uint32_t index, ldp_entity ** entity);
12350 +extern mpls_return_enum ldp_global_find_fec_index(ldp_global * g,
12351 + uint32_t index, ldp_fec ** fec);
12352 +extern mpls_return_enum ldp_global_find_fec(ldp_global * g, mpls_fec * m,
12353 + ldp_fec ** fec);
12355 +extern mpls_return_enum ldp_global_find_inlabel_index(ldp_global * g, uint32_t,
12356 + ldp_inlabel ** inlabel);
12357 +extern mpls_return_enum ldp_global_find_outlabel_index(ldp_global * g, uint32_t,
12358 + ldp_outlabel ** outlabel);
12359 +extern ldp_outlabel *ldp_global_find_outlabel_handle(ldp_global * g,
12360 + mpls_outsegment_handle handle);
12362 +extern mpls_return_enum ldp_global_find_tunnel_index(ldp_global * g,
12363 + uint32_t index, ldp_tunnel ** tunnel);
12364 +extern mpls_return_enum ldp_global_find_resource_index(ldp_global * g,
12365 + uint32_t index, ldp_resource ** resource);
12366 +extern mpls_return_enum ldp_global_find_hop_list_index(ldp_global * g,
12367 + uint32_t index, ldp_hop_list ** hop_list);
12369 +extern void _ldp_global_add_entity(ldp_global * g, ldp_entity * e);
12370 +extern void _ldp_global_del_entity(ldp_global * g, ldp_entity * e);
12372 +extern void _ldp_global_add_session(ldp_global * g, ldp_session * s);
12373 +extern void _ldp_global_del_session(ldp_global * g, ldp_session * s);
12375 +extern void _ldp_global_add_peer(ldp_global * g, ldp_peer * p);
12376 +extern void _ldp_global_del_peer(ldp_global * g, ldp_peer * p);
12378 +extern void _ldp_global_add_fec(ldp_global * g, ldp_fec * l);
12379 +extern void _ldp_global_del_fec(ldp_global * g, ldp_fec * l);
12381 +extern void _ldp_global_add_nexthop(ldp_global * g, ldp_nexthop * l);
12382 +extern void _ldp_global_del_nexthop(ldp_global * g, ldp_nexthop * l);
12384 +extern void _ldp_global_add_attr(ldp_global * g, ldp_attr * a);
12385 +extern void _ldp_global_del_attr(ldp_global * g, ldp_attr * a);
12387 +extern void _ldp_global_add_if(ldp_global * g, ldp_if * i);
12388 +extern void _ldp_global_del_if(ldp_global * g, ldp_if * i);
12390 +extern void _ldp_global_add_addr(ldp_global * g, ldp_addr * a);
12391 +extern void _ldp_global_del_addr(ldp_global * g, ldp_addr * a);
12393 +extern void _ldp_global_add_adj(ldp_global * g, ldp_adj * a);
12394 +extern void _ldp_global_del_adj(ldp_global * g, ldp_adj * a);
12396 +extern mpls_return_enum _ldp_global_add_inlabel(ldp_global * g, ldp_inlabel * i);
12397 +extern mpls_return_enum _ldp_global_del_inlabel(ldp_global * g, ldp_inlabel * i);
12399 +extern mpls_return_enum _ldp_global_add_outlabel(ldp_global * g,
12400 + ldp_outlabel * o);
12401 +extern mpls_return_enum _ldp_global_del_outlabel(ldp_global * g,
12402 + ldp_outlabel * o);
12404 +extern void _ldp_global_add_tunnel(ldp_global * g, ldp_tunnel * t);
12405 +extern void _ldp_global_del_tunnel(ldp_global * g, ldp_tunnel * t);
12407 +extern void _ldp_global_add_resource(ldp_global * g, ldp_resource * r);
12408 +extern void _ldp_global_del_resource(ldp_global * g, ldp_resource * r);
12410 +extern void _ldp_global_add_hop_list(ldp_global * g, ldp_hop_list * h);
12411 +extern void _ldp_global_del_hop_list(ldp_global * g, ldp_hop_list * h);
12413 +#endif
12414 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp.h quagga-mpls/ldpd/ldp.h
12415 --- quagga/ldpd/ldp.h 1969-12-31 18:00:00.000000000 -0600
12416 +++ quagga-mpls/ldpd/ldp.h 2006-08-09 22:02:25.000000000 -0500
12417 @@ -0,0 +1,61 @@
12418 +#ifndef LDP_H
12419 +#define LDP_H
12421 +#include <zebra.h>
12422 +#include "sockunion.h"
12423 +#include "prefix.h"
12424 +#include "zclient.h"
12425 +#include "linklist.h"
12426 +#include "if.h"
12428 +#include "ldp_struct.h"
12430 +#define LDP_DEFAULT_CONFIG "ldpd.conf"
12431 +#define LDP_VTY_PORT 2610
12433 +typedef enum {
12434 + LDP_EGRESS_ALL,
12435 + LDP_EGRESS_LSRID,
12436 + LDP_EGRESS_CONNECTED
12437 +} ldp_egress_mode;
12439 +typedef enum {
12440 + LDP_ADDRESS_ALL,
12441 + LDP_ADDRESS_LSRID,
12442 + LDP_ADDRESS_LDP
12443 +} ldp_address_mode;
12445 +typedef enum {
12446 + LDP_TRANS_ADDR_NONE = 0,
12447 + LDP_TRANS_ADDR_INTERFACE,
12448 + LDP_TRANS_ADDR_LSRID,
12449 + LDP_TRANS_ADDR_STATIC_IP,
12450 + LDP_TRANS_ADDR_STATIC_INTERFACE,
12451 +} ldp_trans_addr_mode;
12453 +struct ldp {
12454 + struct list *peer_list;
12455 + mpls_cfg_handle h;
12456 + mpls_bool admin_up;
12457 + mpls_bool lsr_id_is_static;
12458 + ldp_egress_mode egress;
12459 + ldp_address_mode address;
12460 + ldp_trans_addr_mode trans_addr;
12461 + char trans_addr_ifname[IFNAMSIZ + 1];
12462 + mpls_bool use_lsr_id_for_global_trans_addr;
12463 + mpls_bool use_interface_addr_for_local_trans_addr;
12466 +struct ldp *ldp_get();
12467 +struct ldp *ldp_new();
12468 +void ldp_init();
12469 +int ldp_router_id_update(struct ldp *ldp, struct prefix *router_id);
12470 +int do_ldp_router_id_update(struct ldp *ldp, unsigned int router_id);
12471 +void ldp_finish(struct ldp *ldp);
12473 +int ldp_admin_state_start(struct ldp *ldp);
12474 +int ldp_admin_state_finish(struct ldp *ldp);
12475 +int ldp_add_ipv4(struct ldp *ldp, mpls_fec *fec, mpls_nexthop *nexthop);
12476 +int ldp_delete_ipv4(struct ldp *ldp, mpls_fec *fec, mpls_nexthop *nexthop);
12478 +#endif
12479 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_hello.c quagga-mpls/ldpd/ldp_hello.c
12480 --- quagga/ldpd/ldp_hello.c 1969-12-31 18:00:00.000000000 -0600
12481 +++ quagga-mpls/ldpd/ldp_hello.c 2006-08-09 23:55:17.000000000 -0500
12482 @@ -0,0 +1,297 @@
12485 + * Copyright (C) James R. Leu 2000
12486 + * jleu@mindspring.com
12488 + * This software is covered under the LGPL, for more
12489 + * info check out http://www.gnu.org/copyleft/lgpl.html
12490 + */
12492 +#include <stdio.h>
12493 +#include <sys/socket.h>
12495 +#include "ldp_struct.h"
12496 +#include "ldp_hello.h"
12497 +#include "ldp_mesg.h"
12498 +#include "ldp_buf.h"
12499 +#include "ldp_adj.h"
12500 +#include "ldp_hello.h"
12501 +#include "ldp_entity.h"
12502 +#include "ldp_session.h"
12503 +#include "ldp_inet_addr.h"
12504 +#include "ldp_pdu_setup.h"
12506 +#include "mpls_assert.h"
12507 +#include "mpls_socket_impl.h"
12508 +#include "mpls_timer_impl.h"
12509 +#include "mpls_lock_impl.h"
12510 +#include "mpls_trace_impl.h"
12512 +void ldp_hello_timeout_callback(mpls_timer_handle timer, void *extra,
12513 + mpls_cfg_handle handle)
12515 + ldp_adj *a = (ldp_adj *) extra;
12516 + ldp_global *g = (ldp_global*)handle;
12518 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_TIMER,
12519 + "Hello Timout fired: adj(%d)\n", a->index);
12521 + mpls_lock_get(g->global_lock);
12523 + if (a->session) {
12524 + a->session->shutdown_notif = LDP_NOTIF_HOLD_TIMER_EXPIRED;
12525 + a->session->shutdown_fatal = MPLS_BOOL_FALSE;
12527 + ldp_adj_shutdown(g, a);
12528 + /* timer is deleted inside of ldp_adj_shutdown */
12529 + /* the refcount release for the time is done in ldp_adj_shutdown as well */
12531 + mpls_lock_release(g->global_lock);
12534 +void ldp_hello_send_callback(mpls_timer_handle timer, void *extra,
12535 + mpls_cfg_handle handle)
12537 + ldp_entity *e = (ldp_entity*)extra;
12538 + ldp_global *g = (ldp_global*)handle;
12540 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_TIMER,
12541 + "Hello Send fired: entity(%d)\n", e->index);
12543 + mpls_lock_get(g->global_lock);
12545 + ldp_hello_send(g, e);
12547 + mpls_lock_release(g->global_lock);
12550 +mpls_return_enum ldp_hello_send(ldp_global * g, ldp_entity * e)
12552 + ldp_mesg **hello = NULL;
12553 + mpls_timer_handle *timer;
12554 + int *oper_duration = 0;
12555 + int targeted = 0;
12556 + int duration = 0;
12557 + int request = 0;
12559 + MPLS_ASSERT(g != NULL && e != NULL);
12561 + switch (e->entity_type) {
12562 + case LDP_DIRECT:
12563 + MPLS_ASSERT(e->p.iff != NULL);
12564 + hello = &e->p.iff->hello;
12565 + oper_duration = &e->p.iff->hellotime_send_timer_duration;
12566 + timer = &e->p.iff->hellotime_send_timer;
12567 + targeted = 0;
12568 + request = 0;
12569 + break;
12570 + case LDP_INDIRECT:
12571 + MPLS_ASSERT(e->p.peer != NULL);
12572 + hello = &e->p.peer->hello;
12573 + oper_duration = &e->p.peer->hellotime_send_timer_duration;
12574 + timer = &e->p.peer->hellotime_send_timer;
12575 + targeted = 1;
12576 + if (e->p.peer->target_role == LDP_ACTIVE) {
12577 + request = 1;
12578 + } else {
12579 + request = 0;
12581 + break;
12582 + default:
12583 + MPLS_ASSERT(0);
12585 + if (!*hello) {
12586 + *hello = ldp_hello_create(g->message_identifier++,
12587 + e->hellotime_timer, &e->transport_address,
12588 + g->configuration_sequence_number, targeted, request);
12591 + duration = e->hellotime_interval;
12593 + if (mpls_timer_handle_verify(g->timer_handle, *timer) == MPLS_BOOL_FALSE) {
12594 + MPLS_REFCNT_HOLD(e);
12595 + *timer = mpls_timer_create(g->timer_handle, MPLS_UNIT_SEC,
12596 + duration, (void *)e, g, ldp_hello_send_callback);
12597 + if (mpls_timer_handle_verify(g->timer_handle, *timer) == MPLS_BOOL_FALSE) {
12598 + *oper_duration = 0;
12599 + MPLS_REFCNT_RELEASE(e, ldp_entity_delete);
12600 + return MPLS_FAILURE;
12602 + *oper_duration = duration;
12603 + mpls_timer_start(g->timer_handle, *timer, MPLS_TIMER_REOCCURRING);
12604 + } else {
12605 + if ((*oper_duration) != duration) {
12606 + mpls_timer_stop(g->timer_handle, *timer);
12607 + *oper_duration = duration;
12608 + mpls_timer_modify(g->timer_handle, *timer, duration);
12609 + mpls_timer_start(g->timer_handle, *timer, MPLS_TIMER_REOCCURRING);
12613 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_PERIODIC,
12614 + "Hello Send: entity(%d)\n", e->index);
12616 + return ldp_mesg_send_udp(g, e, *hello);
12619 +ldp_mesg *ldp_hello_create(uint32_t msgid, int holdtime, mpls_inet_addr * traddr,
12620 + uint32_t confnum, int targeted, int request)
12622 + mplsLdpHelloMsg_t *hello = NULL;
12623 + ldp_mesg *msg = NULL;
12625 + msg = ldp_mesg_create();
12626 + ldp_mesg_prepare(msg, MPLS_HELLO_MSGTYPE, msgid);
12627 + if (msg != NULL) {
12628 + hello = &msg->u.hello;
12630 + hello->trAdrTlvExists = 0;
12631 + hello->csnTlvExists = 0;
12633 + hello->chpTlvExists = 1;
12635 + /* this assumes we always want to receive updates for targeted hellos */
12636 + hello->baseMsg.msgLength += setupChpTlv(&(hello->chp), targeted,
12637 + request, 0, holdtime);
12639 + if (traddr && traddr->type == MPLS_FAMILY_IPV4 && traddr->u.ipv4 > 0) {
12640 + hello->trAdrTlvExists = 1;
12641 + hello->baseMsg.msgLength +=
12642 + setupTrAddrTlv(&(hello->trAdr), traddr->u.ipv4);
12645 + if (confnum > 0) {
12646 + hello->csnTlvExists = 1;
12647 + hello->baseMsg.msgLength += setupCsnTlv(&(hello->csn), confnum);
12650 + return msg;
12653 +mpls_return_enum ldp_hello_process(ldp_global * g, ldp_adj * a, ldp_entity *e,
12654 + int hellotime, uint32_t csn, mpls_inet_addr * traddr, int targeted,
12655 + int request)
12657 + mpls_inet_addr *local = NULL, *remote = NULL;
12659 + MPLS_ASSERT(a && e);
12661 + LDP_ENTER(g->user_data, "ldp_hello_process: a = %p, e = %p", a, e);
12663 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_PERIODIC,
12664 + "Hello Recv: entity(%d)\n", e->index);
12666 + switch (e->entity_type) {
12667 + case LDP_DIRECT:
12668 + /* ldp-11 3.5.2. Hello Message */
12669 + if (hellotime == 0) {
12670 + hellotime = 15;
12673 + if (MPLS_LIST_HEAD(&e->p.iff->addr_root)) {
12674 + local = &(MPLS_LIST_HEAD(&e->p.iff->addr_root)->address);
12675 + } else {
12676 + local = &g->lsr_identifier;
12679 + break;
12680 + case LDP_INDIRECT:
12681 + /* ldp-11 3.5.2. Hello Message */
12682 + if (hellotime == 0) {
12683 + hellotime = 45;
12686 + local = &g->lsr_identifier;
12687 + break;
12688 + default:
12689 + MPLS_ASSERT(0);
12692 + if (hellotime < e->hellotime_timer) {
12693 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_NORMAL,
12694 + "ldp_hello_process: adjusting hellotime_timer to match adj\n");
12695 + e->hellotime_timer = hellotime;
12698 + if (traddr != NULL) {
12699 + memcpy(&a->remote_transport_address, traddr, sizeof(struct mpls_inet_addr));
12702 + if (csn != a->remote_csn) {
12703 + /* the remote csn changes all we can do is clear the backoff time */
12704 + /* this will only enable a lsr in the active role to try again */
12705 + a->remote_csn = csn;
12706 + if (a->session && mpls_timer_handle_verify(g->timer_handle,
12707 + a->session->backoff_timer) == MPLS_BOOL_TRUE) {
12708 + ldp_session_backoff_stop(g, a->session);
12712 + /* JLEU should verify that the hello hasn't changed */
12714 + if (a->session) {
12715 + /* && a->session->state == LDP_STATE_OPERATIONAL) */
12716 + /* all that matters is that we have a session in progress */
12717 + /* we already have an established session */
12718 + LDP_EXIT(g->user_data, "ldp_hello_process");
12719 + return MPLS_SUCCESS;
12722 + if (e->transport_address.type != MPLS_FAMILY_NONE) {
12723 + local = &e->transport_address;
12726 + if (a->remote_transport_address.type != MPLS_FAMILY_NONE) {
12727 + remote = &a->remote_transport_address;
12728 + } else {
12729 + remote = &a->remote_source_address;
12732 + switch (mpls_inet_addr_compare(local, remote)) {
12733 + case 1:
12734 + /* if at one point we through WE were passive */
12735 + if (a->role == LDP_PASSIVE && a->session) {
12736 + ldp_session_shutdown(g, a->session, MPLS_BOOL_TRUE);
12738 + a->role = LDP_ACTIVE;
12740 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_STATE,
12741 + "ldp_hello_process: ACTIVE(%d)\n", a->index);
12743 + if (ldp_session_create_active(g, a) != MPLS_SUCCESS) {
12744 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_NORMAL,
12745 + "ldp_hello_process: creating an active session failed(%d)\n",
12746 + a->index);
12747 + /* return FAILURE so we don't try to continue with the new adj */
12748 + return MPLS_FAILURE;
12750 + break;
12751 + case -1:
12752 + /* if at one point we through WE were active */
12753 + if (a->role == LDP_ACTIVE && a->session) {
12754 + ldp_session_shutdown(g, a->session, MPLS_BOOL_TRUE);
12756 + a->role = LDP_PASSIVE;
12758 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_STATE,
12759 + "ldp_hello_process: PASSIVE(%d)\n", a->index);
12761 + break;
12762 + default:
12763 + LDP_PRINT(g->user_data,
12764 + "ldp_hello_process: exit(%d) configuration error\n", a->index);
12766 + if (a->session) {
12767 + ldp_session_shutdown(g, a->session, MPLS_BOOL_TRUE);
12769 + a->role = LDP_NONE;
12770 + MPLS_ASSERT(a->session == NULL);
12772 + /* return FAILURE so we don't try to continue with the new adj */
12773 + LDP_EXIT(g->user_data, "ldp_hello_process: FAILURE");
12774 + return MPLS_FAILURE;
12776 + LDP_EXIT(g->user_data, "ldp_hello_process");
12778 + return MPLS_SUCCESS;
12780 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_hello.h quagga-mpls/ldpd/ldp_hello.h
12781 --- quagga/ldpd/ldp_hello.h 1969-12-31 18:00:00.000000000 -0600
12782 +++ quagga-mpls/ldpd/ldp_hello.h 2006-08-09 21:56:11.000000000 -0500
12783 @@ -0,0 +1,27 @@
12786 + * Copyright (C) James R. Leu 2000
12787 + * jleu@mindspring.com
12789 + * This software is covered under the LGPL, for more
12790 + * info check out http://www.gnu.org/copyleft/lgpl.html
12791 + */
12793 +#ifndef _LDP_HELLO_H_
12794 +#define _LDP_HELLO_H_
12796 +extern void ldp_hello_timeout_callback(mpls_timer_handle timer, void *extra,
12797 + mpls_cfg_handle g);
12799 +extern void ldp_hello_send_callback(mpls_timer_handle timer, void *extra,
12800 + mpls_cfg_handle g);
12801 +extern mpls_return_enum ldp_hello_send(ldp_global * g, ldp_entity * e);
12803 +extern ldp_mesg *ldp_hello_create(uint32_t msgid, int holdtime,
12804 + mpls_inet_addr * traddr, uint32_t confnum, int targeted, int request);
12806 +extern mpls_return_enum ldp_hello_process(ldp_global * g, ldp_adj * a,
12807 + ldp_entity *e, int hellotime, uint32_t csn, mpls_inet_addr * traddr,
12808 + int target, int request);
12810 +#endif
12811 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_hop.c quagga-mpls/ldpd/ldp_hop.c
12812 --- quagga/ldpd/ldp_hop.c 1969-12-31 18:00:00.000000000 -0600
12813 +++ quagga-mpls/ldpd/ldp_hop.c 2006-08-09 21:56:14.000000000 -0500
12814 @@ -0,0 +1,64 @@
12817 + * Copyright (C) James R. Leu 2001
12818 + * jleu@mindspring.com
12820 + * This software is covered under the LGPL, for more
12821 + * info check out http://www.gnu.org/copyleft/lgpl.html
12822 + */
12824 +#include "ldp_struct.h"
12825 +#include "ldp_hop_list.h"
12826 +#include "ldp_hop.h"
12828 +#include "mpls_assert.h"
12829 +#include "mpls_mm_impl.h"
12830 +#include "mpls_trace_impl.h"
12832 +ldp_hop *ldp_hop_create()
12834 + ldp_hop *h = (ldp_hop *) mpls_malloc(sizeof(ldp_hop));
12836 + if (h) {
12837 + memset(h, 0, sizeof(ldp_hop));
12838 + MPLS_REFCNT_INIT(h, 0);
12839 + MPLS_LIST_ELEM_INIT(h, _hop_list);
12841 + return h;
12844 +void ldp_hop_delete(ldp_hop * h)
12846 + // LDP_PRINT(g->user_data,"hop delete\n");
12847 + MPLS_REFCNT_ASSERT(h, 0);
12848 + mpls_free(h);
12851 +mpls_return_enum _ldp_hop_add_hop_list(ldp_hop * h, ldp_hop_list * hl)
12853 + if (h && hl) {
12854 + MPLS_REFCNT_HOLD(hl);
12855 + h->hop_list = hl;
12856 + return MPLS_SUCCESS;
12858 + return MPLS_FAILURE;
12861 +mpls_return_enum _ldp_hop_del_hop_list(ldp_hop * h)
12863 + if (h && h->hop_list) {
12864 + MPLS_REFCNT_RELEASE(h->hop_list, ldp_hop_list_delete);
12865 + h->hop_list = NULL;
12866 + return MPLS_SUCCESS;
12868 + return MPLS_FAILURE;
12871 +mpls_bool ldp_hop_in_use(ldp_hop * h)
12873 + if (h->hop_list && h->hop_list->tunnel &&
12874 + (h->hop_list->tunnel->admin_state == MPLS_ADMIN_ENABLE)) {
12875 + return MPLS_BOOL_TRUE;
12877 + return MPLS_BOOL_FALSE;
12879 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_hop.h quagga-mpls/ldpd/ldp_hop.h
12880 --- quagga/ldpd/ldp_hop.h 1969-12-31 18:00:00.000000000 -0600
12881 +++ quagga-mpls/ldpd/ldp_hop.h 2006-08-09 21:56:11.000000000 -0500
12882 @@ -0,0 +1,23 @@
12885 + * Copyright (C) James R. Leu 2001
12886 + * jleu@mindspring.com
12888 + * This software is covered under the LGPL, for more
12889 + * info check out http://www.gnu.org/copyleft/lgpl.html
12890 + */
12892 +#ifndef _LDP_HOP_H_
12893 +#define _LDP_HOP_H_
12895 +#include "ldp_struct.h"
12897 +extern ldp_hop *ldp_hop_create();
12898 +extern void ldp_hop_delete(ldp_hop * h);
12900 +extern mpls_return_enum _ldp_hop_add_hop_list(ldp_hop * h, ldp_hop_list * hl);
12901 +extern mpls_return_enum _ldp_hop_del_hop_list(ldp_hop * h);
12903 +extern mpls_bool ldp_hop_in_use(ldp_hop * h);
12905 +#endif
12906 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_hop_list.c quagga-mpls/ldpd/ldp_hop_list.c
12907 --- quagga/ldpd/ldp_hop_list.c 1969-12-31 18:00:00.000000000 -0600
12908 +++ quagga-mpls/ldpd/ldp_hop_list.c 2006-08-09 21:56:14.000000000 -0500
12909 @@ -0,0 +1,133 @@
12912 + * Copyright (C) James R. Leu 2001
12913 + * jleu@mindspring.com
12915 + * This software is covered under the LGPL, for more
12916 + * info check out http://www.gnu.org/copyleft/lgpl.html
12917 + */
12919 +#include "ldp_struct.h"
12920 +#include "ldp_hop_list.h"
12921 +#include "ldp_hop.h"
12922 +#include "ldp_tunnel.h"
12924 +#include "mpls_assert.h"
12925 +#include "mpls_mm_impl.h"
12926 +#include "mpls_trace_impl.h"
12928 +static uint32_t _ldp_hop_list_next_index = 1;
12930 +ldp_hop_list *ldp_hop_list_create()
12932 + ldp_hop_list *h = (ldp_hop_list *) mpls_malloc(sizeof(ldp_hop_list));
12934 + if (h) {
12935 + memset(h, 0, sizeof(ldp_hop_list));
12936 + MPLS_REFCNT_INIT(h, 0);
12937 + MPLS_LIST_ELEM_INIT(h, _global);
12938 + MPLS_LIST_INIT(&h->hop, ldp_hop);
12940 + h->index = _ldp_hop_list_get_next_index();
12942 + return h;
12945 +void ldp_hop_list_delete(ldp_hop_list * h)
12947 + // LDP_PRINT(g->user_data,"hop_list delete\n");
12948 + MPLS_REFCNT_ASSERT(h, 0);
12949 + mpls_free(h);
12952 +uint32_t _ldp_hop_list_get_next_index()
12954 + uint32_t retval = _ldp_hop_list_next_index;
12956 + _ldp_hop_list_next_index++;
12957 + if (retval > _ldp_hop_list_next_index) {
12958 + _ldp_hop_list_next_index = 1;
12960 + return retval;
12963 +mpls_return_enum ldp_hop_list_find_hop_index(ldp_hop_list * hl, uint32_t index,
12964 + ldp_hop ** hop)
12966 + ldp_hop *h = NULL;
12968 + if (hl && index > 0) {
12969 + /* because we sort our inserts by index, this lets us know
12970 + if we've "walked" past the end of the list */
12972 + h = MPLS_LIST_TAIL(&hl->hop);
12973 + if (h == NULL || h->index < index) {
12974 + *hop = NULL;
12975 + return MPLS_END_OF_LIST;
12978 + h = MPLS_LIST_HEAD(&hl->hop);
12979 + while (h != NULL) {
12980 + if (h->index == index) {
12981 + *hop = h;
12982 + return MPLS_SUCCESS;
12984 + h = MPLS_LIST_NEXT(&hl->hop, h, _hop_list);
12987 + *hop = NULL;
12988 + return MPLS_FAILURE;
12991 +mpls_return_enum ldp_hop_list_add_hop(ldp_hop_list * hl, ldp_hop * h)
12993 + ldp_hop *hp = NULL;
12995 + if (hl && h) {
12996 + MPLS_REFCNT_HOLD(h);
12997 + hp = MPLS_LIST_HEAD(&hl->hop);
12998 + while (hp != NULL) {
12999 + if (hp->index > h->index) {
13000 + MPLS_LIST_INSERT_BEFORE(&hl->hop, hp, h, _hop_list);
13001 + _ldp_hop_add_hop_list(h, hl);
13002 + return MPLS_SUCCESS;
13004 + hp = MPLS_LIST_NEXT(&hl->hop, hp, _hop_list);
13006 + MPLS_LIST_ADD_TAIL(&hl->hop, h, _hop_list, ldp_hop);
13007 + _ldp_hop_add_hop_list(h, hl);
13008 + return MPLS_SUCCESS;
13010 + return MPLS_FAILURE;
13013 +mpls_return_enum ldp_hop_list_del_hop(ldp_hop_list * hl, ldp_hop * h)
13015 + if (hl && h) {
13016 + MPLS_LIST_REMOVE(&hl->hop, h, _hop_list);
13017 + _ldp_hop_del_hop_list(h);
13018 + MPLS_REFCNT_RELEASE(h, ldp_hop_delete);
13019 + return MPLS_SUCCESS;
13021 + return MPLS_FAILURE;
13024 +mpls_return_enum _ldp_hop_list_add_tunnel(ldp_hop_list * h, ldp_tunnel * t)
13026 + if (h && t) {
13027 + MPLS_REFCNT_HOLD(t);
13028 + h->tunnel = t;
13029 + return MPLS_SUCCESS;
13031 + return MPLS_FAILURE;
13034 +mpls_return_enum _ldp_hop_list_del_tunnel(ldp_hop_list * h)
13036 + if (h && h->tunnel) {
13037 + MPLS_REFCNT_RELEASE(h->tunnel, ldp_tunnel_delete);
13038 + h->tunnel = NULL;
13039 + return MPLS_SUCCESS;
13041 + return MPLS_FAILURE;
13043 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_hop_list.h quagga-mpls/ldpd/ldp_hop_list.h
13044 --- quagga/ldpd/ldp_hop_list.h 1969-12-31 18:00:00.000000000 -0600
13045 +++ quagga-mpls/ldpd/ldp_hop_list.h 2006-08-09 21:56:14.000000000 -0500
13046 @@ -0,0 +1,30 @@
13049 + * Copyright (C) James R. Leu 2001
13050 + * jleu@mindspring.com
13052 + * This software is covered under the LGPL, for more
13053 + * info check out http://www.gnu.org/copyleft/lgpl.html
13054 + */
13056 +#ifndef _LDP_HOP_LIST_H_
13057 +#define _LDP_HOP_LIST_H_
13059 +#include "ldp_struct.h"
13061 +extern ldp_hop_list *ldp_hop_list_create();
13062 +extern void ldp_hop_list_delete(ldp_hop_list * h);
13063 +extern uint32_t _ldp_hop_list_get_next_index();
13065 +extern mpls_return_enum ldp_hop_list_find_hop_index(ldp_hop_list * hl,
13066 + uint32_t index, ldp_hop ** hop);
13068 +extern mpls_return_enum ldp_hop_list_add_hop(ldp_hop_list * hl, ldp_hop * e);
13069 +extern mpls_return_enum ldp_hop_list_del_hop(ldp_hop_list * hl, ldp_hop * e);
13071 +extern mpls_return_enum _ldp_hop_list_add_tunnel(ldp_hop_list * h,
13073 + ldp_tunnel * t);
13074 +extern mpls_return_enum _ldp_hop_list_del_tunnel(ldp_hop_list * h);
13076 +#endif
13077 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_if.c quagga-mpls/ldpd/ldp_if.c
13078 --- quagga/ldpd/ldp_if.c 1969-12-31 18:00:00.000000000 -0600
13079 +++ quagga-mpls/ldpd/ldp_if.c 2006-12-07 22:04:57.000000000 -0600
13080 @@ -0,0 +1,332 @@
13083 + * Copyright (C) James R. Leu 2000
13084 + * jleu@mindspring.com
13086 + * This software is covered under the LGPL, for more
13087 + * info check out http://www.gnu.org/copyleft/lgpl.html
13088 + */
13090 +#include <stdlib.h>
13091 +#include <netinet/in.h>
13092 +#include <sys/socket.h>
13093 +#include "ldp_struct.h"
13094 +#include "ldp_global.h"
13095 +#include "ldp_entity.h"
13096 +#include "ldp_nexthop.h"
13097 +#include "ldp_nortel.h"
13098 +#include "ldp_addr.h"
13099 +#include "ldp_if.h"
13100 +#include "ldp_fec.h"
13101 +#include "ldp_mesg.h"
13102 +#include "ldp_buf.h"
13103 +#include "ldp_hello.h"
13105 +#include "mpls_assert.h"
13106 +#include "mpls_mm_impl.h"
13107 +#include "mpls_compare.h"
13108 +#include "mpls_socket_impl.h"
13109 +#include "mpls_timer_impl.h"
13110 +#include "mpls_ifmgr_impl.h"
13111 +#include "mpls_trace_impl.h"
13113 +extern uint32_t _ldp_sub_entity_next_index;
13115 +ldp_if *ldp_if_create(ldp_global *g)
13117 + ldp_if *i = (ldp_if *) mpls_malloc(sizeof(ldp_if));
13119 + if (i) {
13120 + memset(i, 0, sizeof(ldp_if));
13121 + /*
13122 + * note: this is init to 1 for a reason!
13123 + * We're placing it in the global list, so this is our refcnt
13124 + * when this refcnt gets to zero, it will be removed from the
13125 + * global list and deleted
13126 + */
13127 + /*
13128 + * TESTING: jleu 6/7/2004, since I want the iff to be cleaned up
13129 + * when it no longer has a nexthop, fec, or label, the only things that
13130 + * should increment the ref are those (nh, fec, label etc), not global
13131 + * nor inserting into the tree.
13132 + MPLS_REFCNT_INIT(i, 1);
13133 + */
13134 + MPLS_LIST_ELEM_INIT(i, _global);
13135 + MPLS_LIST_INIT(&i->nh_root, ldp_nexthop);
13136 + MPLS_LIST_INIT(&i->addr_root, ldp_addr);
13137 + i->label_space = -1;
13138 + i->dest.addr.type = MPLS_FAMILY_IPV4;
13139 + i->dest.addr.u.ipv4 = INADDR_ALLRTRS_GROUP;
13140 + i->tx_buffer = ldp_buf_create(MPLS_PDUMAXLEN);
13141 + i->tx_message = ldp_mesg_create();
13142 + i->index = _ldp_if_get_next_index();
13143 + i->oper_state = MPLS_OPER_DOWN;
13144 + i->is_p2p = MPLS_BOOL_FALSE;
13145 + _ldp_global_add_if(g, i);
13147 + return i;
13150 +void ldp_if_delete(ldp_global *g, ldp_if * i)
13152 + LDP_PRINT(g->user_data, "if delete: %p", i);
13153 + MPLS_REFCNT_ASSERT(i, 0);
13154 + mpls_free(i->tx_buffer);
13155 + mpls_free(i->tx_message);
13156 + i->tx_buffer = NULL;
13157 + i->tx_message = NULL;
13158 + _ldp_global_del_if(g, i);
13159 + mpls_free(i);
13163 + * ldp_if_insert and ldp_if_remove should ONLY be used in conjuction with
13164 + * adding and removing nexthops (or fecs).
13165 + */
13167 +ldp_if *ldp_if_insert(ldp_global *g, mpls_if_handle handle)
13169 + ldp_if *iff = NULL;
13171 + MPLS_ASSERT(g);
13172 + MPLS_ASSERT(mpls_if_handle_verify(g->ifmgr_handle, handle) == MPLS_BOOL_TRUE);
13174 + if ((iff = ldp_if_create(g)) == NULL) {
13175 + LDP_PRINT(g->user_data,"ldp_if_insert: unable to alloc ldp_if\n");
13176 + return NULL;
13178 + iff->handle = handle;
13179 + return iff;
13182 +#if 0
13183 +void ldp_if_remove(ldp_global *g, ldp_if *iff)
13185 + MPLS_ASSERT(g && iff);
13186 + MPLS_REFCNT_RELEASE2(g, iff, ldp_if_delete);
13188 +#endif
13191 + * We do not hold a ref to the nexthop. The nexthop holds a ref to the
13192 + * if. Nexthop creation calls ldp_if_add_nexthop, nexthop deletion
13193 + * calls ldp_if_del_nexthop. There is no way a nexthop can be deleted
13194 + * without removing the ifs ref to the nexthop.
13195 + */
13196 +void ldp_if_add_nexthop(ldp_if * i, ldp_nexthop * n)
13198 + ldp_nexthop *np = NULL;
13200 + MPLS_ASSERT(i && n);
13202 + ldp_nexthop_add_if(n,i);
13204 + np = MPLS_LIST_HEAD(&i->nh_root);
13205 + while (np != NULL) {
13206 + if (np->index > n->index) {
13207 + MPLS_LIST_INSERT_BEFORE(&i->nh_root, np, n, _if);
13208 + return;
13210 + np = MPLS_LIST_NEXT(&i->nh_root, np, _if);
13212 + MPLS_LIST_ADD_TAIL(&i->nh_root, n, _if, ldp_nexthop);
13215 +void ldp_if_del_nexthop(ldp_global *g, ldp_if * i, ldp_nexthop * n)
13217 + MPLS_ASSERT(i && n);
13218 + MPLS_LIST_REMOVE(&i->nh_root, n, _if);
13219 + ldp_nexthop_del_if(g, n);
13222 +void ldp_if_add_addr(ldp_if * i, ldp_addr * a)
13224 + ldp_addr *ap = NULL;
13226 + MPLS_ASSERT(i && a);
13227 + MPLS_REFCNT_HOLD(a);
13229 + ldp_addr_add_if(a,i);
13231 + ap = MPLS_LIST_HEAD(&i->addr_root);
13232 + while (ap != NULL) {
13233 + if (ap->index > a->index) {
13234 + MPLS_LIST_INSERT_BEFORE(&i->addr_root, ap, a, _if);
13235 + return;
13237 + ap = MPLS_LIST_NEXT(&i->addr_root, ap, _if);
13239 + MPLS_LIST_ADD_TAIL(&i->addr_root, a, _if, ldp_addr);
13242 +void ldp_if_del_addr(ldp_global *g, ldp_if * i, ldp_addr * a)
13244 + MPLS_ASSERT(i && a);
13245 + MPLS_LIST_REMOVE(&i->addr_root, a, _if);
13246 + ldp_addr_del_if(g, a);
13247 + MPLS_REFCNT_RELEASE2(g, a, ldp_addr_delete);
13250 +mpls_return_enum ldp_if_find_addr_index(ldp_if *i, int index, ldp_addr **a)
13252 + ldp_addr *ap = NULL;
13254 + MPLS_ASSERT(i);
13256 + if (index > 0) {
13258 + /* because we sort our inserts by index, this lets us know
13259 + if we've "walked" past the end of the list */
13261 + ap = MPLS_LIST_TAIL(&i->addr_root);
13262 + if (!ap || ap->index < index) {
13263 + *a = NULL;
13264 + return MPLS_END_OF_LIST;
13267 + ap = MPLS_LIST_HEAD(&i->addr_root);
13268 + do {
13269 + if (ap->index == index) {
13270 + *a = ap;
13271 + return MPLS_SUCCESS;
13273 + } while((ap = MPLS_LIST_NEXT(&i->addr_root, ap, _if)));
13275 + *a = NULL;
13276 + return MPLS_FAILURE;
13279 +ldp_addr *ldp_if_addr_find(ldp_if *i, mpls_inet_addr *a)
13281 + ldp_addr *ap = NULL;
13283 + MPLS_ASSERT(i && a);
13285 + ap = MPLS_LIST_HEAD(&i->addr_root);
13287 + while(ap) {
13288 + if (!mpls_inet_addr_compare(&ap->address, a)) {
13289 + return ap;
13291 + ap = MPLS_LIST_NEXT(&i->addr_root, ap, _if);
13293 + return NULL;
13296 +mpls_return_enum ldp_if_startup(ldp_global * g, ldp_if * i)
13298 + ldp_entity *e = NULL;
13300 + LDP_ENTER(g->user_data, "ldp_if_startup");
13302 + MPLS_ASSERT(i != NULL);
13303 + e = i->entity;
13304 + MPLS_ASSERT(e != NULL);
13305 + MPLS_ASSERT(e->p.iff != NULL);
13307 + if (mpls_socket_multicast_if_join(g->socket_handle, g->hello_socket, i,
13308 + &i->dest.addr) == MPLS_FAILURE) {
13309 + goto ldp_if_startup_delay;
13312 + i->dest.port = e->remote_udp_port;
13313 + if (ldp_hello_send(g, e) == MPLS_FAILURE) {
13314 + ldp_if_shutdown(g, i);
13315 + return MPLS_FAILURE;
13317 + i->oper_state = MPLS_OPER_UP;
13319 + LDP_EXIT(g->user_data, "ldp_if_startup");
13321 + return MPLS_SUCCESS;
13323 +ldp_if_startup_delay:
13325 + /*
13326 + * when a interface update comes in, it will search the global
13327 + * list of interfaces, and start up the interface then
13328 + */
13329 + i->oper_state = MPLS_OPER_DOWN;
13331 + LDP_EXIT(g->user_data, "ldp_if_startup-delayed");
13333 + return MPLS_SUCCESS;
13336 +mpls_return_enum ldp_if_shutdown(ldp_global * g, ldp_if * i)
13338 + ldp_entity *e = NULL;
13340 + MPLS_ASSERT(i != NULL && ((e = i->entity) != NULL));
13342 + LDP_ENTER(g->user_data, "ldp_if_shutdown");
13344 + i->oper_state = MPLS_OPER_DOWN;
13346 + mpls_socket_multicast_if_drop(g->socket_handle, g->hello_socket, i,
13347 + &i->dest.addr);
13349 + mpls_timer_stop(g->timer_handle, i->hellotime_send_timer);
13350 + mpls_timer_delete(g->timer_handle, i->hellotime_send_timer);
13351 + i->hellotime_send_timer_duration = 0;
13352 + i->hellotime_send_timer = 0;
13354 + /* the entity is held in ldp_hello_send when it creates the timer
13355 + * ldp_hello_send is called by ldp_if_startup
13356 + */
13357 + MPLS_ASSERT(e != NULL);
13358 + MPLS_REFCNT_RELEASE(e, ldp_entity_delete);
13360 + if (i->hello) {
13361 + ldp_mesg_delete(i->hello);
13362 + i->hello = NULL;
13365 + LDP_EXIT(g->user_data, "ldp_if_shutdown");
13367 + return MPLS_SUCCESS;
13370 +mpls_bool ldp_if_is_active(ldp_if * i)
13372 + if (i && i->entity && i->entity->admin_state == MPLS_ADMIN_ENABLE)
13373 + return MPLS_BOOL_TRUE;
13375 + return MPLS_BOOL_FALSE;
13378 +mpls_return_enum _ldp_if_add_entity(ldp_if * i, ldp_entity * e)
13380 + if (i && e) {
13381 + MPLS_REFCNT_HOLD(e);
13382 + i->entity = e;
13383 + return MPLS_SUCCESS;
13385 + return MPLS_FAILURE;
13388 +ldp_entity *ldp_if_get_entity(ldp_if * i)
13390 + return i->entity;
13393 +mpls_return_enum _ldp_if_del_entity(ldp_if * i)
13395 + if (i && i->entity) {
13396 + MPLS_REFCNT_RELEASE(i->entity, ldp_entity_delete);
13397 + i->entity = NULL;
13398 + return MPLS_SUCCESS;
13400 + return MPLS_FAILURE;
13403 +uint32_t _ldp_if_get_next_index()
13405 + uint32_t retval = _ldp_sub_entity_next_index;
13407 + _ldp_sub_entity_next_index++;
13408 + if (retval > _ldp_sub_entity_next_index) {
13409 + _ldp_sub_entity_next_index = 1;
13411 + return retval;
13413 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_if.h quagga-mpls/ldpd/ldp_if.h
13414 --- quagga/ldpd/ldp_if.h 1969-12-31 18:00:00.000000000 -0600
13415 +++ quagga-mpls/ldpd/ldp_if.h 2006-08-09 21:56:10.000000000 -0500
13416 @@ -0,0 +1,34 @@
13419 + * Copyright (C) James R. Leu 2000
13420 + * jleu@mindspring.com
13422 + * This software is covered under the LGPL, for more
13423 + * info check out http://www.gnu.org/copyleft/lgpl.html
13424 + */
13426 +#ifndef _LDP_IF_H_
13427 +#define _LDP_IF_H_
13429 +#include "ldp_struct.h"
13431 +extern ldp_if *ldp_if_create(ldp_global *g);
13432 +extern void ldp_if_delete(ldp_global *g, ldp_if * i);
13433 +extern ldp_if *ldp_if_insert(ldp_global *g, mpls_if_handle handle);
13434 +extern void ldp_if_remove(ldp_global *g, ldp_if *iff);
13435 +extern void ldp_if_add_nexthop(ldp_if * i, ldp_nexthop * n);
13436 +extern void ldp_if_del_nexthop(ldp_global *g, ldp_if * i, ldp_nexthop * n);
13437 +extern ldp_addr *ldp_if_addr_find(ldp_if *i, mpls_inet_addr *a);
13438 +extern mpls_return_enum ldp_if_find_addr_index(ldp_if *i, int index,
13439 + ldp_addr **a);
13440 +extern void ldp_if_del_addr(ldp_global *g, ldp_if * i, ldp_addr * a);
13441 +extern void ldp_if_add_addr(ldp_if * i, ldp_addr * a);
13442 +extern mpls_return_enum ldp_if_startup(ldp_global * g, ldp_if * i);
13443 +extern mpls_return_enum ldp_if_shutdown(ldp_global * g, ldp_if * i);
13444 +extern mpls_bool ldp_if_is_active(ldp_if * i);
13445 +extern mpls_return_enum _ldp_if_add_entity(ldp_if * i, ldp_entity * e);
13446 +extern ldp_entity *ldp_if_get_entity(ldp_if * i);
13447 +extern mpls_return_enum _ldp_if_del_entity(ldp_if * i);
13448 +extern uint32_t _ldp_if_get_next_index();
13450 +#endif
13451 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_inet_addr.c quagga-mpls/ldpd/ldp_inet_addr.c
13452 --- quagga/ldpd/ldp_inet_addr.c 1969-12-31 18:00:00.000000000 -0600
13453 +++ quagga-mpls/ldpd/ldp_inet_addr.c 2006-08-09 21:56:15.000000000 -0500
13454 @@ -0,0 +1,23 @@
13457 + * Copyright (C) James R. Leu 2000
13458 + * jleu@mindspring.com
13460 + * This software is covered under the LGPL, for more
13461 + * info check out http://www.gnu.org/copyleft/lgpl.html
13462 + */
13464 +#include "ldp_struct.h"
13465 +#include "ldp_inet_addr.h"
13467 +#include "mpls_mm_impl.h"
13469 +mpls_inet_addr *mpls_inet_addr_create()
13471 + mpls_inet_addr *ia = (mpls_inet_addr *) mpls_malloc(sizeof(mpls_inet_addr));
13473 + if (ia != NULL)
13474 + memset(ia, 0, sizeof(mpls_inet_addr));
13476 + return ia;
13478 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_inet_addr.h quagga-mpls/ldpd/ldp_inet_addr.h
13479 --- quagga/ldpd/ldp_inet_addr.h 1969-12-31 18:00:00.000000000 -0600
13480 +++ quagga-mpls/ldpd/ldp_inet_addr.h 2006-08-09 21:56:13.000000000 -0500
13481 @@ -0,0 +1,17 @@
13484 + * Copyright (C) James R. Leu 2000
13485 + * jleu@mindspring.com
13487 + * This software is covered under the LGPL, for more
13488 + * info check out http://www.gnu.org/copyleft/lgpl.html
13489 + */
13491 +#ifndef _LDP_INET_ADDR_H_
13492 +#define _LDP_INET_ADDR_H_
13494 +extern mpls_inet_addr *mpls_inet_addr_create();
13495 +extern mpls_bool mpls_inet_addr_is_equal(mpls_inet_addr *, mpls_inet_addr *);
13496 +extern int mpls_inet_addr_compare(mpls_inet_addr *, mpls_inet_addr *);
13498 +#endif
13499 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_init.c quagga-mpls/ldpd/ldp_init.c
13500 --- quagga/ldpd/ldp_init.c 1969-12-31 18:00:00.000000000 -0600
13501 +++ quagga-mpls/ldpd/ldp_init.c 2006-08-09 21:56:16.000000000 -0500
13502 @@ -0,0 +1,235 @@
13505 + * Copyright (C) James R. Leu 2000
13506 + * jleu@mindspring.com
13508 + * This software is covered under the LGPL, for more
13509 + * info check out http://www.gnu.org/copyleft/lgpl.html
13510 + */
13512 +#include "ldp_struct.h"
13513 +#include "ldp_mesg.h"
13514 +#include "ldp_entity.h"
13515 +#include "ldp_nortel.h"
13516 +#include "ldp_buf.h"
13517 +#include "ldp_pdu_setup.h"
13519 +#include "mpls_assert.h"
13520 +#include "mpls_socket_impl.h"
13521 +#include "mpls_trace_impl.h"
13522 +#if MPLS_USE_LSR
13523 +#include "lsr_cfg.h"
13524 +#else
13525 +#include "mpls_mpls_impl.h"
13526 +#endif
13528 +void ldp_init_prepare(ldp_mesg * msg, ldp_global * g, uint32_t msgid,
13529 + ldp_session * s)
13531 + mplsLdpInitMsg_t *init = NULL;
13532 + uint32_t remote_labelspace;
13533 + uint32_t path_vector_limit;
13534 + uint32_t remote_lsraddr;
13535 + uint8_t direction = 0;
13536 + ldp_adj *a = MPLS_LIST_HEAD(&s->adj_root);
13537 + uint32_t loop = 0;
13538 + uint8_t merge = 0;
13539 + mpls_range range;
13540 + uint8_t len = 0;
13542 + MPLS_ASSERT(s && a);
13544 + LDP_ENTER(g->user_data, "ldp_init_create");
13546 + ldp_mesg_prepare(msg, MPLS_INIT_MSGTYPE, msgid);
13547 + init = &msg->u.init;
13549 + remote_lsraddr = a->remote_lsr_address.u.ipv4;
13550 + remote_labelspace = a->remote_label_space;
13552 + loop = (s->cfg_loop_detection_mode == LDP_LOOP_NONE) ? (0) : (1);
13553 + if (loop == LDP_LOOP_NONE) {
13554 + path_vector_limit = 0;
13555 + } else {
13556 + path_vector_limit = s->cfg_path_vector_limit;
13559 + init->cspExists = 1;
13561 + init->baseMsg.msgLength += setupCspTlv(&(init->csp), s->cfg_keepalive,
13562 + s->cfg_distribution_mode, loop, path_vector_limit, s->cfg_max_pdu,
13563 + remote_lsraddr, remote_labelspace, 0);
13565 + init->aspExists = 0;
13566 + init->fspExists = 0;
13568 + range.label_space = s->cfg_label_space;
13569 +#if MPLS_USE_LSR
13570 +#else
13571 + mpls_mpls_get_label_space_range(g->mpls_handle,&range);
13572 +#endif
13574 + switch (range.type) {
13575 + case MPLS_LABEL_RANGE_ATM_VP:
13576 + MPLS_ASSERT(0);
13577 + case MPLS_LABEL_RANGE_ATM_VC:
13578 + case MPLS_LABEL_RANGE_ATM_VP_VC:
13579 + init->aspExists = 1;
13580 + init->baseMsg.msgLength += setupAspTlv(&(init->asp), merge, direction);
13581 + init->baseMsg.msgLength += addLblRng2AspTlv(&(init->asp),
13582 + range.min.u.atm.vpi, range.min.u.atm.vci, range.max.u.atm.vpi,
13583 + range.max.u.atm.vci);
13584 + break;
13585 + case MPLS_LABEL_RANGE_FR_10:
13586 + len = 0; /* Section 3.5.3 fspTlv */
13587 + case MPLS_LABEL_RANGE_FR_24:
13588 + init->fspExists = 1;
13590 + if (range.type == MPLS_LABEL_RANGE_FR_24) {
13591 + len = 2; /* Section 3.5.3 fspTlv */
13594 + init->baseMsg.msgLength += setupFspTlv(&(init->fsp), merge, direction);
13595 + init->baseMsg.msgLength += addLblRng2FspTlv(&(init->fsp), 0, len,
13596 + range.min.u.fr.dlci, 0, range.max.u.fr.dlci);
13597 + break;
13598 + case MPLS_LABEL_RANGE_GENERIC:
13599 + break;
13601 + LDP_EXIT(g->user_data, "ldp_init_create");
13604 +mpls_return_enum ldp_init_send(ldp_global * g, ldp_session * s)
13606 + mpls_return_enum result = MPLS_FAILURE;
13608 + MPLS_ASSERT(s);
13610 + LDP_ENTER(g->user_data, "ldp_init_send");
13612 + ldp_init_prepare(s->tx_message, g, g->message_identifier++, s);
13614 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_INIT,
13615 + "Init Send: session(%d)\n", s->index);
13617 + result = ldp_mesg_send_tcp(g, s, s->tx_message);
13619 + LDP_EXIT(g->user_data, "ldp_init_send");
13621 + return result;
13624 +mpls_return_enum ldp_init_process(ldp_global * g, ldp_session * s,
13625 + ldp_mesg * msg)
13627 + mpls_range range;
13629 + MPLS_MSGPTR(Init);
13631 + MPLS_ASSERT(s);
13633 + LDP_ENTER(g->user_data, "ldp_init_process");
13635 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
13636 + "Init Recv: session(%d)\n", s->index);
13638 + MPLS_MSGPARAM(Init) = &msg->u.init;
13640 + range.label_space = s->cfg_label_space;
13642 +#if MPLS_USE_LSR
13643 + range.type = MPLS_LABEL_RANGE_GENERIC;
13644 +#else
13645 + mpls_mpls_get_label_space_range(g->mpls_handle, &range);
13646 +#endif
13648 + if (MPLS_MSGPARAM(Init)->csp.rcvLsrAddress != g->lsr_identifier.u.ipv4 ||
13649 + MPLS_MSGPARAM(Init)->csp.rcvLsId != range.label_space) {
13650 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
13651 + "Init failed(%d): sending bad LDP-ID\n", s->index);
13652 + LDP_EXIT(g->user_data, "ldp_init_process-error");
13653 + s->shutdown_notif = LDP_NOTIF_BAD_LDP_ID;
13654 + s->shutdown_fatal = MPLS_BOOL_FALSE;
13655 + return MPLS_FAILURE;
13658 + if (MPLS_MSGPARAM(Init)->csp.holdTime == 0) {
13659 + LDP_EXIT(g->user_data, "ldp_init_process-error");
13660 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
13661 + "Init failed(%d): sending bad Keepalive Time\n", s->index);
13662 + s->shutdown_notif = LDP_NOTIF_SESSION_REJECTED_BAD_KEEPALIVE_TIME;
13663 + s->shutdown_fatal = MPLS_BOOL_FALSE;
13664 + return MPLS_FAILURE;
13667 + if (MPLS_MSGPARAM(Init)->csp.maxPduLen <= 255)
13668 + MPLS_MSGPARAM(Init)->csp.maxPduLen = 4096; /* Section 3.5.3. */
13670 + s->remote_max_pdu = MPLS_MSGPARAM(Init)->csp.maxPduLen;
13671 + s->remote_keepalive = MPLS_MSGPARAM(Init)->csp.holdTime;
13672 + s->remote_path_vector_limit = MPLS_MSGPARAM(Init)->csp.flags.flags.pvl;
13673 + s->remote_distribution_mode =
13674 + (ldp_distribution_mode) MPLS_MSGPARAM(Init)->csp.flags.flags.lad;
13676 + if (s->remote_keepalive < s->cfg_keepalive) {
13677 + s->oper_keepalive = s->remote_keepalive;
13678 + } else {
13679 + s->oper_keepalive = s->cfg_keepalive;
13682 + /* JLEU: eventually this should be configured by the user */
13683 + s->oper_keepalive_interval = s->oper_keepalive / 3;
13685 + if (MPLS_MSGPARAM(Init)->csp.flags.flags.ld == 0) {
13686 + s->remote_loop_detection = MPLS_BOOL_FALSE;
13687 + } else {
13688 + s->remote_loop_detection = MPLS_BOOL_TRUE;
13691 + if (s->remote_max_pdu < s->cfg_max_pdu) {
13692 + s->oper_max_pdu = s->remote_max_pdu;
13695 + if (s->remote_distribution_mode != s->cfg_distribution_mode) {
13696 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
13697 + "Init(%d): distribution modes do not match, using default\n", s->index);
13698 + if (range.type == MPLS_LABEL_RANGE_GENERIC) {
13699 + s->oper_distribution_mode = LDP_DISTRIBUTION_UNSOLICITED;
13700 + } else {
13701 + s->oper_distribution_mode = LDP_DISTRIBUTION_ONDEMAND;
13705 + if ((s->remote_loop_detection == MPLS_BOOL_TRUE) &&
13706 + (g->loop_detection_mode != LDP_LOOP_NONE)) {
13707 + s->oper_loop_detection = s->cfg_loop_detection_mode;
13708 + } else {
13709 + s->oper_loop_detection = LDP_LOOP_NONE;
13712 + if (MPLS_MSGPARAM(Init)->aspExists) {
13713 + if (range.type >= MPLS_LABEL_RANGE_ATM_VP && range.type <= MPLS_LABEL_RANGE_ATM_VP_VC) {
13714 + MPLS_ASSERT(0);
13715 + } else {
13716 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
13717 + "Init Failed(%d): sending bad Label Range (ATM)\n", s->index);
13718 + s->shutdown_notif = LDP_NOTIF_SESSION_REJECTED_PARAMETERS_LABEL_RANGE;
13719 + s->shutdown_fatal = MPLS_BOOL_FALSE;
13720 + return MPLS_FAILURE;
13722 + } else if (MPLS_MSGPARAM(Init)->fspExists) {
13723 + if (range.type >= MPLS_LABEL_RANGE_FR_10 && range.type <= MPLS_LABEL_RANGE_FR_24) {
13724 + MPLS_ASSERT(0);
13725 + } else {
13726 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
13727 + "Init Failed(%d): sending bad Label Range (FR)\n", s->index);
13728 + s->shutdown_notif = LDP_NOTIF_SESSION_REJECTED_PARAMETERS_LABEL_RANGE;
13729 + s->shutdown_fatal = MPLS_BOOL_FALSE;
13730 + return MPLS_FAILURE;
13734 + LDP_EXIT(g->user_data, "ldp_init_process");
13736 + return MPLS_SUCCESS;
13738 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_init.h quagga-mpls/ldpd/ldp_init.h
13739 --- quagga/ldpd/ldp_init.h 1969-12-31 18:00:00.000000000 -0600
13740 +++ quagga-mpls/ldpd/ldp_init.h 2006-08-09 21:56:15.000000000 -0500
13741 @@ -0,0 +1,21 @@
13744 + * Copyright (C) James R. Leu 2000
13745 + * jleu@mindspring.com
13747 + * This software is covered under the LGPL, for more
13748 + * info check out http://www.gnu.org/copyleft/lgpl.html
13749 + */
13751 +#ifndef _LDP_INIT_H_
13752 +#define _LDP_INIT_H_
13754 +#include "ldp_struct.h"
13756 +extern ldp_mesg *ldp_init_create(ldp_global * g, uint32_t msgid,
13757 + ldp_session * session);
13758 +extern mpls_return_enum ldp_init_send(ldp_global * g, ldp_session * s);
13759 +extern mpls_return_enum ldp_init_process(ldp_global * g, ldp_session * s,
13760 + ldp_mesg * msg);
13762 +#endif
13763 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_inlabel.c quagga-mpls/ldpd/ldp_inlabel.c
13764 --- quagga/ldpd/ldp_inlabel.c 1969-12-31 18:00:00.000000000 -0600
13765 +++ quagga-mpls/ldpd/ldp_inlabel.c 2006-12-07 22:04:28.000000000 -0600
13766 @@ -0,0 +1,201 @@
13769 + * Copyright (C) James R. Leu 2000
13770 + * jleu@mindspring.com
13772 + * This software is covered under the LGPL, for more
13773 + * info check out http://www.gnu.org/copyleft/lgpl.html
13774 + */
13776 +#include <stdlib.h>
13777 +#include "ldp_struct.h"
13778 +#include "ldp_outlabel.h"
13779 +#include "ldp_inlabel.h"
13780 +#include "ldp_session.h"
13781 +#include "ldp_entity.h"
13782 +#include "ldp_attr.h"
13783 +#include "ldp_global.h"
13785 +#include "mpls_assert.h"
13786 +#include "mpls_mm_impl.h"
13787 +#include "mpls_trace_impl.h"
13789 +#if MPLS_USE_LSR
13790 +#include "lsr_cfg.h"
13791 +#else
13792 +#include "mpls_mpls_impl.h"
13793 +#endif
13795 +static uint32_t _ldp_inlabel_next_index = 1;
13798 + * even through we're trying to mimic what FECs/addrs/interfaces are doing
13799 + * with respect to being added to the global list upon create and
13800 + * automagically be removed from the global list upon delete, we have to
13801 + * change thing up for inlabels. We want the global add/delete to call
13802 + * the porting layer to install the segments, but an inlabel needs more
13803 + * info then just being allocated before the porting layer can add it.
13804 + * so ldp_inlabel_create is not in charge of adding to the global list.
13805 + * Instead the only entrance to creating a inlabel is
13806 + * ldp_inlabel_create_complete which uses ldp_inlabel_create just to
13807 + * allocate and initialize the memory, then after all of the necessary info
13808 + * has been attached, it is added to the global list, which calls the
13809 + * porting layer
13810 + */
13812 +static ldp_inlabel *ldp_inlabel_create(ldp_global * g)
13814 + ldp_inlabel *i = (ldp_inlabel *) mpls_malloc(sizeof(ldp_inlabel));
13816 + if (i) {
13817 + memset(i, 0, sizeof(ldp_inlabel));
13818 + MPLS_REFCNT_INIT(i, 0);
13819 + mpls_link_list_init(&i->session_root);
13820 + mpls_link_list_init(&i->attr_root);
13821 + MPLS_LIST_ELEM_INIT(i, _global);
13822 + MPLS_LIST_ELEM_INIT(i, _outlabel);
13823 + i->index = _ldp_inlabel_get_next_index();
13824 + i->info.label.type = MPLS_LABEL_TYPE_NONE;
13826 + return i;
13829 +ldp_inlabel *ldp_inlabel_create_complete(ldp_global * g, ldp_session * s,
13830 + ldp_attr * a)
13832 + ldp_inlabel *in = ldp_inlabel_create(g);
13833 + mpls_return_enum result;
13835 + if (in != NULL) {
13837 + in->info.labelspace = s->cfg_label_space;
13838 + in->info.npop = 1;
13839 + in->info.family = MPLS_FAMILY_IPV4;
13840 + in->info.owner = MPLS_OWNER_LDP;
13842 + /* _ldp_global_add_inlabel must be here so the porting layer has all the
13843 + * info needed for installing the label */
13844 + result = _ldp_global_add_inlabel(g, in);
13846 + if (result == MPLS_FAILURE) {
13847 + _ldp_global_del_inlabel(g, in);
13848 + return NULL;
13851 + if (ldp_session_add_inlabel(g, s, in) == MPLS_FAILURE) {
13852 + /* if ldp_session_add_inlabel fails its use of MPLS_HOLD and
13853 + * RELEASE2 will result in the inlabel being deleted */
13854 + return NULL;
13857 + mpls_label_struct2ldp_attr(&in->info.label, a);
13858 + ldp_attr_add_inlabel(g, a, in);
13860 + return in;
13863 +void ldp_inlabel_delete(ldp_global * g, ldp_inlabel * i)
13865 + LDP_PRINT(g->user_data,"inlabel delete: %p", i);
13866 + MPLS_REFCNT_ASSERT(i, 0);
13867 + _ldp_global_del_inlabel(g, i);
13868 + mpls_free(i);
13871 +mpls_return_enum ldp_inlabel_add_outlabel(ldp_global *g, ldp_inlabel *i,
13872 + ldp_outlabel *o) {
13873 + mpls_return_enum result;
13875 + MPLS_ASSERT(i && o);
13876 + MPLS_ASSERT(i->outlabel == NULL);
13878 +#if MPLS_USE_LSR
13880 + lsr_xconnect xcon;
13881 + xcon.insegment_index = i->info.handle;
13882 + xcon.outsegment_index = o->info.handle;
13883 + xcon.info.owner = MPLS_OWNER_LDP;
13884 + result = lsr_cfg_xconnect_set2(g->lsr_handle, &xcon, LSR_CFG_ADD|
13885 + LSR_XCONNECT_CFG_OUTSEGMENT|LSR_XCONNECT_CFG_INSEGMENT|
13886 + LSR_XCONNECT_CFG_LSPID|LSR_XCONNECT_CFG_OWNER);
13888 +#else
13889 + result = mpls_mpls_xconnect_add(g->mpls_handle, &i->info, &o->info);
13890 +#endif
13891 + if (result == MPLS_SUCCESS) {
13892 + MPLS_REFCNT_HOLD(o);
13893 + i->outlabel = o;
13894 + _ldp_outlabel_add_inlabel(o, i);
13896 + return result;
13899 +mpls_return_enum ldp_inlabel_del_outlabel(ldp_global *g, ldp_inlabel * i)
13901 + MPLS_ASSERT(i && i->outlabel);
13903 +#if MPLS_USE_LSR
13904 + lsr_xconnect xcon;
13905 + xcon.insegment_index = i->info.handle;
13906 + xcon.outsegment_index = i->outlabel->info.handle;
13907 + lsr_cfg_xconnect_set2(g->lsr_handle, &xcon, LSR_CFG_DEL);
13908 +#else
13909 + mpls_mpls_xconnect_del(g->mpls_handle, &i->info, &i->outlabel->info);
13910 +#endif
13911 + _ldp_outlabel_del_inlabel(g, i->outlabel, i);
13912 + MPLS_REFCNT_RELEASE2(g, i->outlabel, ldp_outlabel_delete);
13913 + i->outlabel = NULL;
13915 + return MPLS_SUCCESS;
13918 +mpls_return_enum _ldp_inlabel_add_attr(ldp_global *g, ldp_inlabel * i, ldp_attr * a)
13920 + MPLS_ASSERT(i && a);
13922 + MPLS_REFCNT_HOLD(a);
13923 + if (mpls_link_list_add_tail(&i->attr_root, a) == MPLS_SUCCESS) {
13924 + i->reuse_count++;
13925 + return MPLS_SUCCESS;
13927 + MPLS_REFCNT_RELEASE2(g, a, ldp_attr_delete);
13928 + return MPLS_FAILURE;
13931 +void _ldp_inlabel_del_attr(ldp_global *g, ldp_inlabel * i, ldp_attr * a)
13933 + MPLS_ASSERT(i && a);
13934 + mpls_link_list_remove_data(&i->attr_root, a);
13935 + MPLS_REFCNT_RELEASE2(g, a, ldp_attr_delete);
13936 + i->reuse_count--;
13939 +mpls_return_enum _ldp_inlabel_add_session(ldp_inlabel * i, ldp_session * s)
13941 + MPLS_ASSERT(i && s);
13943 + MPLS_REFCNT_HOLD(s);
13944 + if (mpls_link_list_add_tail(&i->session_root, s) == MPLS_SUCCESS) {
13945 + return MPLS_SUCCESS;
13947 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
13948 + return MPLS_FAILURE;
13951 +void _ldp_inlabel_del_session(ldp_inlabel * i, ldp_session * s)
13953 + MPLS_ASSERT(i && s);
13954 + mpls_link_list_remove_data(&i->session_root, s);
13955 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
13958 +uint32_t _ldp_inlabel_get_next_index()
13960 + uint32_t retval = _ldp_inlabel_next_index;
13962 + _ldp_inlabel_next_index++;
13963 + if (retval > _ldp_inlabel_next_index) {
13964 + _ldp_inlabel_next_index = 1;
13966 + return retval;
13968 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_inlabel.h quagga-mpls/ldpd/ldp_inlabel.h
13969 --- quagga/ldpd/ldp_inlabel.h 1969-12-31 18:00:00.000000000 -0600
13970 +++ quagga-mpls/ldpd/ldp_inlabel.h 2006-10-16 22:30:21.000000000 -0500
13971 @@ -0,0 +1,36 @@
13974 + * Copyright (C) James R. Leu 2000
13975 + * jleu@mindspring.com
13977 + * This software is covered under the LGPL, for more
13978 + * info check out http://www.gnu.org/copyleft/lgpl.html
13979 + */
13981 +#ifndef _LDP_INLABEL_H_
13982 +#define _LDP_INLABEL_H_
13984 +#include "ldp_struct.h"
13986 +extern void ldp_inlabel_delete(ldp_global * g, ldp_inlabel * i);
13988 +extern ldp_inlabel *ldp_inlabel_create_complete(ldp_global * g, ldp_session * s,
13989 + ldp_attr * a);
13990 +extern void ldp_inlabel_delete_complete(ldp_global * g, ldp_inlabel * in,
13991 + ldp_session * s, ldp_attr * a);
13993 +extern mpls_return_enum ldp_inlabel_add_outlabel(ldp_global *g,
13994 + ldp_inlabel *i, ldp_outlabel *o);
13995 +extern mpls_return_enum ldp_inlabel_del_outlabel(ldp_global *g,
13996 + ldp_inlabel *i);
13998 +extern mpls_return_enum _ldp_inlabel_add_session(ldp_inlabel * i,
13999 + ldp_session * s);
14000 +extern void _ldp_inlabel_del_session(ldp_inlabel * i, ldp_session * s);
14002 +extern uint32_t _ldp_inlabel_get_next_index();
14004 +extern mpls_return_enum _ldp_inlabel_add_attr(ldp_global *g, ldp_inlabel * i, ldp_attr * a);
14005 +extern void _ldp_inlabel_del_attr(ldp_global *g, ldp_inlabel * i, ldp_attr * a);
14007 +#endif
14008 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_interface.c quagga-mpls/ldpd/ldp_interface.c
14009 --- quagga/ldpd/ldp_interface.c 1969-12-31 18:00:00.000000000 -0600
14010 +++ quagga-mpls/ldpd/ldp_interface.c 2008-02-28 21:47:40.000000000 -0600
14011 @@ -0,0 +1,208 @@
14012 +#include <zebra.h>
14014 +#include "if.h"
14015 +#include "memory.h"
14017 +#include "ldp_cfg.h"
14018 +#include "ldp_struct.h"
14020 +#include "ldp.h"
14021 +#include "ldp_interface.h"
14022 +#include "impl_mpls.h"
14024 +extern struct prefix router_id;
14026 +unsigned int if_ipv4_src_address (struct interface *ifp) {
14027 + struct listnode *node;
14028 + struct connected *c;
14029 + for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, c))
14031 + struct prefix *p = c->address;
14033 + if (p && p->family == AF_INET)
14034 + return p->u.prefix4.s_addr;
14036 + return router_id.u.prefix4.s_addr;
14039 +struct ldp_interface *ldp_interface_new(struct interface *ifp) {
14040 + struct ldp_interface *li;
14042 + li = XMALLOC(MTYPE_LDP, sizeof(struct ldp_interface));
14043 + if (!li) {
14044 + return NULL;
14046 + memset(li, 0, sizeof(struct ldp_interface));
14047 + li->ifp = ifp;
14048 + ifp->info = li;
14050 + li->configured = MPLS_BOOL_FALSE;
14051 + li->admin_up = MPLS_BOOL_FALSE;
14052 + li->create_on_hold = MPLS_BOOL_TRUE;
14053 + ldp_entity_set_defaults(&li->entity);
14055 + return li;
14058 +void ldp_interface_free(struct ldp_interface *li) {
14059 + XFREE(MTYPE_LDP, li);
14062 +int ldp_interface_create2(struct ldp_interface *li) {
14063 + struct ldp *ldp = ldp_get();
14065 + if (!ldp || !li->iff.index) {
14066 + li->create_on_hold = MPLS_BOOL_TRUE;
14067 + return MPLS_SUCCESS;
14070 + li->create_on_hold = MPLS_BOOL_FALSE;
14072 + li->entity.sub_index = li->iff.index;
14073 + li->entity.entity_type = LDP_DIRECT;
14074 + li->entity.admin_state = MPLS_ADMIN_DISABLE;
14076 + if (ldp->trans_addr == LDP_TRANS_ADDR_INTERFACE) {
14077 + li->entity.transport_address.type = MPLS_FAMILY_IPV4;
14078 + li->entity.transport_address.u.ipv4 =
14079 + ntohl(if_ipv4_src_address (li->ifp));
14080 + } else {
14081 + li->entity.transport_address.type = MPLS_FAMILY_NONE;
14084 + ldp_cfg_entity_set(ldp->h, &li->entity,
14085 + LDP_CFG_ADD | LDP_ENTITY_CFG_SUB_INDEX |
14086 + LDP_ENTITY_CFG_ADMIN_STATE | LDP_ENTITY_CFG_TRANS_ADDR);
14088 + ldp_cfg_entity_get(ldp->h, &li->entity, 0xFFFFFFFF);
14089 + return ldp_interface_admin_state_finish(li);
14092 +int ldp_interface_create(struct ldp_interface *li) {
14093 + struct ldp *ldp = ldp_get();
14095 + MPLS_ASSERT (!li->iff.index);
14096 + MPLS_ASSERT(ldp);
14098 + /* tell LDP about this interface */
14099 + if (li->ifp->mpls_labelspace < 0) {
14100 + li->ifp->mpls_labelspace = 0;
14102 + li->iff.label_space = li->ifp->mpls_labelspace;
14103 + li->iff.handle = li->ifp;
14105 + zlog_debug("Creating interface %s(%p)\n", li->ifp->name, li->ifp);
14107 + ldp_cfg_if_set(ldp->h, &li->iff,LDP_CFG_ADD|LDP_IF_CFG_LABEL_SPACE);
14108 + ldp_cfg_if_get(ldp->h, &li->iff, 0xFFFFFFFF);
14110 + return MPLS_SUCCESS;
14113 +void ldp_interface_delete2(struct ldp_interface *li) {
14114 + struct ldp *ldp = ldp_get();
14116 + li->create_on_hold = MPLS_BOOL_TRUE;
14117 + li->entity.admin_state = MPLS_ADMIN_DISABLE;
14119 + if (ldp) {
14120 + ldp_interface_admin_state_start(li);
14121 + if (li->entity.index) {
14122 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_CFG_DEL);
14125 + li->entity.index = 0;
14128 +void ldp_interface_delete(struct ldp_interface *li) {
14129 + struct ldp *ldp = ldp_get();
14131 + MPLS_ASSERT(ldp);
14132 + MPLS_ASSERT(li->iff.index);
14134 + ldp_cfg_if_set(ldp->h, &li->iff, LDP_CFG_DEL);
14135 + li->iff.index = 0;
14138 +int ldp_interface_startup(struct ldp_interface *li) {
14139 + struct ldp *ldp = ldp_get();
14141 + MPLS_ASSERT(ldp && li->iff.index && li->entity.index);
14143 + /* only real interfaces get here */
14144 + li->entity.admin_state = MPLS_ADMIN_ENABLE;
14145 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_ADMIN_STATE);
14147 + return MPLS_SUCCESS;
14150 +int ldp_interface_shutdown(struct ldp_interface *li) {
14151 + struct ldp *ldp = ldp_get();
14153 + MPLS_ASSERT(ldp && li->iff.index && li->entity.index);
14155 + li->entity.admin_state = MPLS_ADMIN_DISABLE;
14156 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_ADMIN_STATE);
14158 + return MPLS_SUCCESS;
14161 +int ldp_interface_admin_state_start(struct ldp_interface *li) {
14162 + if (li->admin_up == MPLS_BOOL_TRUE && ldp_interface_is_up(li)) {
14163 + return ldp_interface_shutdown(li);
14165 + return MPLS_SUCCESS;
14168 +int ldp_interface_admin_state_finish(struct ldp_interface *li) {
14169 + if (li->admin_up == MPLS_BOOL_TRUE && ldp_interface_is_up(li)) {
14170 + return ldp_interface_startup(li);
14172 + return MPLS_SUCCESS;
14175 +void ldp_interface_up(struct ldp_interface *li) {
14176 + if (li->configured == MPLS_BOOL_TRUE && li->admin_up == MPLS_BOOL_TRUE) {
14177 + ldp_interface_startup(li);
14181 +void ldp_interface_down(struct ldp_interface *li) {
14182 + if (li->configured == MPLS_BOOL_TRUE && li->admin_up == MPLS_BOOL_TRUE) {
14183 + ldp_interface_shutdown(li);
14187 +int ldp_interface_is_up(struct ldp_interface *li) {
14188 + return if_is_up(li->ifp);
14191 +static
14192 +int ldp_interface_new_hook(struct interface *ifp) {
14193 + if (!ldp_interface_new(ifp)) {
14194 + return 1;
14197 + if (ldp_get())
14198 + ldp_interface_create(ifp->info);
14200 + return 0;
14203 +static
14204 +int ldp_interface_delete_hook(struct interface *ifp) {
14205 + if (ifp->info) {
14206 + if (ldp_get())
14207 + ldp_interface_delete(ifp->info);
14208 + ldp_interface_free(ifp->info);
14210 + ifp->info = NULL;
14211 + return 0;
14214 +void ldp_interface_init() {
14215 + /* Initialize Zebra interface data structure. */
14216 + if_init();
14217 + if_add_hook(IF_NEW_HOOK, ldp_interface_new_hook);
14218 + if_add_hook(IF_DELETE_HOOK, ldp_interface_delete_hook);
14220 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_interface.h quagga-mpls/ldpd/ldp_interface.h
14221 --- quagga/ldpd/ldp_interface.h 1969-12-31 18:00:00.000000000 -0600
14222 +++ quagga-mpls/ldpd/ldp_interface.h 2008-02-28 21:42:28.000000000 -0600
14223 @@ -0,0 +1,49 @@
14224 +#ifndef LDP_IF_H
14225 +#define LDP_IF_H
14227 +#include <zebra.h>
14229 +#include "if.h"
14230 +#include "command.h"
14231 +#include "prefix.h"
14232 +#include "zclient.h"
14234 +#include "ldp_struct.h"
14235 +#include "l2cc_interface.h"
14237 +struct ldp_interface {
14238 + struct interface *ifp;
14239 + struct connected *connected;
14240 + struct l2cc_interface *l2cc;
14242 + ldp_entity entity;
14243 + ldp_if iff;
14244 + mpls_bool configured;
14245 + mpls_bool admin_up;
14246 + mpls_bool create_on_hold;
14247 + mpls_bool use_for_global_trans_addr;
14248 + mpls_bool use_for_local_trans_addr;
14251 +unsigned int if_ipv4_src_address (struct interface *ifp);
14253 +struct ldp_interface *ldp_interface_new(struct interface *ifp);
14254 +void ldp_interface_free(struct ldp_interface *li);
14256 +void ldp_interface_up(struct ldp_interface *li);
14257 +void ldp_interface_down(struct ldp_interface *li);
14259 +int ldp_interface_startup(struct ldp_interface *li);
14260 +int ldp_interface_shutdown(struct ldp_interface *li);
14262 +int ldp_interface_create2(struct ldp_interface *li);
14263 +void ldp_interface_delete2(struct ldp_interface *li);
14264 +int ldp_interface_create(struct ldp_interface *li);
14265 +void ldp_interface_delete(struct ldp_interface *li);
14266 +int ldp_interface_admin_state_start(struct ldp_interface *li);
14267 +int ldp_interface_admin_state_finish(struct ldp_interface *li);
14268 +int ldp_interface_is_up(struct ldp_interface *li);
14270 +void ldp_interface_init();
14272 +#endif
14273 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_keepalive.c quagga-mpls/ldpd/ldp_keepalive.c
14274 --- quagga/ldpd/ldp_keepalive.c 1969-12-31 18:00:00.000000000 -0600
14275 +++ quagga-mpls/ldpd/ldp_keepalive.c 2006-08-09 21:56:16.000000000 -0500
14276 @@ -0,0 +1,127 @@
14279 + * Copyright (C) James R. Leu 2000
14280 + * jleu@mindspring.com
14282 + * This software is covered under the LGPL, for more
14283 + * info check out http://www.gnu.org/copyleft/lgpl.html
14284 + */
14286 +#include "ldp_struct.h"
14287 +#include "ldp_mesg.h"
14288 +#include "ldp_nortel.h"
14289 +#include "ldp_buf.h"
14290 +#include "ldp_keepalive.h"
14291 +#include "ldp_session.h"
14292 +#include "ldp_pdu_setup.h"
14294 +#include "mpls_assert.h"
14295 +#include "mpls_socket_impl.h"
14296 +#include "mpls_timer_impl.h"
14297 +#include "mpls_lock_impl.h"
14298 +#include "mpls_trace_impl.h"
14300 +void ldp_keepalive_timeout_callback(mpls_timer_handle timer, void *extra,
14301 + mpls_cfg_handle handle)
14303 + ldp_session *s = (ldp_session *) extra;
14304 + ldp_global *g = (ldp_global*)handle;
14306 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_TIMER,
14307 + "Keepalive Timeout fired: session(%d)\n", s->index);
14309 + mpls_lock_get(g->global_lock);
14311 + s->shutdown_notif = LDP_NOTIF_KEEPALIVE_TIMER_EXPIRED;
14312 + s->shutdown_fatal = MPLS_BOOL_FALSE;
14313 + /* we should go into backoff, so don't completly kill the session */
14314 + ldp_session_shutdown(g, s, MPLS_BOOL_FALSE);
14315 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
14317 + mpls_lock_release(g->global_lock);
14320 +void ldp_keepalive_send_callback(mpls_timer_handle timer, void *extra,
14321 + mpls_cfg_handle handle)
14323 + ldp_session *s = (ldp_session *) extra;
14324 + ldp_global *g = (ldp_global*)handle;
14326 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_TIMER,
14327 + "Keepalive Send fired: session(%d)\n", s->index);
14329 + mpls_lock_get(g->global_lock);
14330 + ldp_keepalive_send(g, s);
14331 + mpls_lock_release(g->global_lock);
14334 +ldp_mesg *ldp_keepalive_create(uint32_t msgid)
14336 + ldp_mesg *msg = NULL;
14338 + msg = ldp_mesg_create();
14339 + ldp_mesg_prepare(msg, MPLS_KEEPAL_MSGTYPE, msgid);
14341 + return msg;
14344 +void ldp_keepalive_set_message_id(ldp_mesg * msg, uint32_t msgid)
14346 + mplsLdpKeepAlMsg_t *keep;
14348 + MPLS_ASSERT(msg);
14349 + keep = &msg->u.keep;
14350 + setBaseMsgId(&(keep->baseMsg), msgid);
14353 +mpls_return_enum ldp_keepalive_send(ldp_global * g, ldp_session * s)
14355 + MPLS_ASSERT(s);
14357 + if (s->keepalive == NULL) {
14358 + if ((s->keepalive = ldp_keepalive_create(g->message_identifier++)) == NULL) {
14359 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ERROR,
14360 + "ldp_keepalive_send: error creating keepalve\n");
14361 + return MPLS_FAILURE;
14363 + } else {
14364 + ldp_keepalive_set_message_id(s->keepalive, g->message_identifier++);
14367 + if (mpls_timer_handle_verify(g->timer_handle, s->keepalive_recv_timer) ==
14368 + MPLS_BOOL_FALSE) {
14369 + MPLS_REFCNT_HOLD(s);
14370 + s->keepalive_recv_timer = mpls_timer_create(g->timer_handle, MPLS_UNIT_SEC,
14371 + s->oper_keepalive, (void *)s, g, ldp_keepalive_timeout_callback);
14372 + if (mpls_timer_handle_verify(g->timer_handle, s->keepalive_recv_timer) ==
14373 + MPLS_BOOL_FALSE) {
14374 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
14375 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ERROR,
14376 + "ldp_keepalive_send: error creating timer\n");
14377 + return MPLS_FAILURE;
14379 + mpls_timer_start(g->timer_handle, s->keepalive_recv_timer, MPLS_TIMER_ONESHOT);
14382 + if (mpls_timer_handle_verify(g->timer_handle, s->keepalive_send_timer) ==
14383 + MPLS_BOOL_FALSE) {
14384 + MPLS_REFCNT_HOLD(s);
14385 + s->keepalive_send_timer = mpls_timer_create(g->timer_handle, MPLS_UNIT_SEC,
14386 + s->oper_keepalive_interval, (void *)s, g, ldp_keepalive_send_callback);
14387 + if (mpls_timer_handle_verify(g->timer_handle, s->keepalive_send_timer) ==
14388 + MPLS_BOOL_FALSE) {
14389 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
14390 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ERROR,
14391 + "ldp_keepalive_send: error creating timer\n");
14392 + return MPLS_FAILURE;
14394 + mpls_timer_start(g->timer_handle, s->keepalive_send_timer, MPLS_TIMER_REOCCURRING);
14397 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_PERIODIC,
14398 + "Keepalive Send: session(%d)\n", s->index);
14400 + ldp_mesg_send_tcp(g, s, s->keepalive);
14402 + return MPLS_SUCCESS;
14404 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_keepalive.h quagga-mpls/ldpd/ldp_keepalive.h
14405 --- quagga/ldpd/ldp_keepalive.h 1969-12-31 18:00:00.000000000 -0600
14406 +++ quagga-mpls/ldpd/ldp_keepalive.h 2006-08-09 21:56:16.000000000 -0500
14407 @@ -0,0 +1,23 @@
14410 + * Copyright (C) James R. Leu 2000
14411 + * jleu@mindspring.com
14413 + * This software is covered under the LGPL, for more
14414 + * info check out http://www.gnu.org/copyleft/lgpl.html
14415 + */
14417 +#ifndef _LDP_KEEPALIVE_H_
14418 +#define _LDP_KEEPALIVE_H_
14420 +#include "ldp_struct.h"
14422 +extern ldp_mesg *ldp_keepalive_create(uint32_t msgid);
14423 +extern mpls_return_enum ldp_keepalive_send(ldp_global * g, ldp_session * s);
14424 +extern void ldp_keepalive_send_callback(mpls_timer_handle timer, void *extra,
14425 + mpls_cfg_handle g);
14426 +extern void ldp_keepalive_timeout_callback(mpls_timer_handle timer, void *extra,
14427 + mpls_cfg_handle g);
14428 +extern void ldp_keepalive_set_message_id(ldp_mesg * keep, uint32_t msgid);
14430 +#endif
14431 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_label_abort.c quagga-mpls/ldpd/ldp_label_abort.c
14432 --- quagga/ldpd/ldp_label_abort.c 1969-12-31 18:00:00.000000000 -0600
14433 +++ quagga-mpls/ldpd/ldp_label_abort.c 2006-08-09 21:56:16.000000000 -0500
14434 @@ -0,0 +1,165 @@
14437 + * Copyright (C) James R. Leu 2000
14438 + * jleu@mindspring.com
14440 + * This software is covered under the LGPL, for more
14441 + * info check out http://www.gnu.org/copyleft/lgpl.html
14442 + */
14444 +#include "ldp_struct.h"
14445 +#include "ldp_attr.h"
14446 +#include "ldp_fec.h"
14447 +#include "ldp_mesg.h"
14448 +#include "ldp_pdu_setup.h"
14449 +#include "ldp_entity.h"
14450 +#include "ldp_session.h"
14451 +#include "ldp_notif.h"
14452 +#include "ldp_label_abort.h"
14453 +#include "ldp_label_rel_with.h"
14454 +#include "ldp_label_mapping.h"
14456 +#include "mpls_trace_impl.h"
14458 +void ldp_label_abort_prepare_msg(ldp_mesg * msg, uint32_t msgid,
14459 + ldp_attr * s_attr)
14461 + mplsLdpLblAbortMsg_t *abrt = NULL;
14463 + ldp_mesg_prepare(msg, MPLS_LBLABORT_MSGTYPE, msgid);
14465 + abrt = &msg->u.abort;
14467 + if (s_attr->fecTlvExists) {
14468 + abrt->fecTlvExists = 1;
14469 + abrt->baseMsg.msgLength += setupFecTlv(&abrt->fecTlv);
14470 + abrt->baseMsg.msgLength +=
14471 + addFecElem2FecTlv(&abrt->fecTlv, &s_attr->fecTlv.fecElArray[0]);
14474 + if (s_attr->lblMsgIdTlvExists) {
14475 + abrt->lblMsgIdTlvExists = 1;
14476 + abrt->baseMsg.msgLength +=
14477 + setupLblMsgIdTlv(&abrt->lblMsgIdTlv, s_attr->msg_id);
14481 +mpls_return_enum ldp_label_abort_send(ldp_global * g, ldp_session * s,
14482 + ldp_attr * s_attr)
14484 + mpls_fec fec;
14485 + ldp_attr *ds_attr = NULL;
14487 + LDP_ENTER(g->user_data, "ldp_label_abort_send");
14489 + fec_tlv2mpls_fec(&s_attr->fecTlv, 0, &fec);
14490 + if ((ds_attr = ldp_attr_find_downstream_state(g, s, &fec,
14491 + LDP_LSP_STATE_ABORT_SENT)) != NULL) {
14492 + return MPLS_SUCCESS;
14495 + ldp_label_abort_prepare_msg(s->tx_message, g->message_identifier++, s_attr);
14497 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_LABEL,
14498 + "Label Abort Sent: session (%d) \n", s->index);
14500 + s_attr->state = LDP_LSP_STATE_ABORT_SENT;
14502 + if (ldp_mesg_send_tcp(g, s, s->tx_message) == MPLS_FAILURE) {
14503 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_ERROR,
14504 + "Label Abort Sent Failed .\n");
14505 + goto ldp_label_abort_send_error;
14508 + LDP_EXIT(g->user_data, "ldp_label_abort_send");
14509 + return MPLS_SUCCESS;
14511 +ldp_label_abort_send_error:
14513 + if (s_attr) {
14514 + ldp_attr_remove_complete(g, s_attr, MPLS_BOOL_FALSE);
14516 + LDP_EXIT(g->user_data, "ldp_label_abort_send-error");
14518 + return MPLS_FAILURE;
14521 +mpls_return_enum ldp_label_abort_process(ldp_global * g, ldp_session * s,
14522 + ldp_adj * a, ldp_entity * e, ldp_attr * r_attr, ldp_fec * f)
14524 + ldp_attr_list *us_list = NULL;
14525 + ldp_attr *us_temp = NULL;
14526 + ldp_attr *us_attr = NULL;
14527 + ldp_attr *ds_req_attr = NULL;
14528 + ldp_attr *ds_map_attr = NULL;
14529 + mpls_return_enum retval = MPLS_SUCCESS;
14531 + if ((us_list = ldp_attr_find_upstream_all2(g, s, f))) {
14532 + us_temp = MPLS_LIST_HEAD(us_list);
14533 + while (us_temp) {
14534 + if (((us_temp->state == LDP_LSP_STATE_REQ_RECV) &&
14535 + (us_temp->msg_id == r_attr->msg_id)) ||
14536 + (us_temp->state == LDP_LSP_STATE_MAP_SENT)) {
14537 + us_attr = us_temp;
14538 + break;
14540 + us_temp = MPLS_LIST_NEXT(us_list, us_temp, _fs);
14543 + if ((!us_attr) || (us_attr->state == LDP_LSP_STATE_MAP_SENT)) { /* LAbR.1,2 */
14544 + retval = MPLS_FAILURE;
14545 + goto LAbR_12;
14547 + /* LAbR.3 */
14548 + if (ldp_notif_send(g, s, us_attr, LDP_NOTIF_LABEL_ABORT) != MPLS_SUCCESS) {
14549 + retval = MPLS_FAILURE;
14550 + goto LAbR_12;
14552 + /* LAbR.4 */
14553 + if (us_attr->ds_attr && (us_attr->ds_attr->state == LDP_LSP_STATE_REQ_SENT)) {
14554 + ds_req_attr = us_attr->ds_attr;
14555 + goto LAbR_7;
14557 + /* LAbR.5 */
14558 + if (us_attr->ds_attr && (us_attr->ds_attr->state == LDP_LSP_STATE_MAP_RECV)) {
14559 + ds_map_attr = us_attr->ds_attr;
14560 + } else {
14561 + goto LAbR_11;
14564 + /* this may results in us sending a label withdraw to s and possibly
14565 + propogating a release */
14566 + if (ldp_label_release_process(g, s, NULL, e, us_attr, f) != MPLS_SUCCESS) { /* LAbR.6 */
14567 + retval = MPLS_FAILURE;
14569 + goto LAbR_11;
14571 +LAbR_7:
14573 + if (g->label_merge == MPLS_BOOL_TRUE) { /* LAbR.7 */
14574 + /* by now us_attr has been removed from the downstream us_attr_root
14575 + so any left overs (reflect by count > 0) are from other peers */
14576 + if (ds_req_attr && ldp_attr_num_us2ds(ds_req_attr)) { /* LAbR.8 */
14577 + goto LAbR_11;
14581 + if (ldp_label_abort_send(g, ds_req_attr->session, ds_req_attr) != MPLS_SUCCESS) { /* LAbR.9,10 */
14582 + retval = MPLS_FAILURE;
14585 +LAbR_11:
14587 + if (us_attr) {
14588 + ldp_attr_remove_complete(g, us_attr, MPLS_BOOL_FALSE);
14591 +LAbR_12:
14593 + LDP_EXIT(g->user_data, "ldp_label_abort_processed");
14594 + return retval;
14597 +void abort2attr(mplsLdpLblAbortMsg_t * abrt, ldp_attr * a, uint32_t flag)
14600 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_label_abort.h quagga-mpls/ldpd/ldp_label_abort.h
14601 --- quagga/ldpd/ldp_label_abort.h 1969-12-31 18:00:00.000000000 -0600
14602 +++ quagga-mpls/ldpd/ldp_label_abort.h 2006-08-09 21:56:15.000000000 -0500
14603 @@ -0,0 +1,28 @@
14606 + * Copyright (C) James R. Leu 2000
14607 + * jleu@mindspring.com
14609 + * This software is covered under the LGPL, for more
14610 + * info check out http://www.gnu.org/copyleft/lgpl.html
14611 + */
14613 +#ifndef _LDP_LABEL_ABORT_H_
14614 +#define _LDP_LABEL_ABORT_H_
14615 +#include "ldp_struct.h"
14617 +extern ldp_mesg *ldp_label_abort_create_msg(uint32_t msgid, ldp_attr * s_attr);
14619 +extern mpls_return_enum ldp_label_abort_send(ldp_global * g, ldp_session * s,
14620 + ldp_attr * a);
14622 +extern mpls_return_enum ldp_label_abort_process(ldp_global * g, ldp_session * s,
14623 + ldp_adj * a, ldp_entity * e, ldp_attr * r_attr, ldp_fec * fec);
14625 +extern void Prepare_Label_Abort_Attributes(ldp_global * g, ldp_session * s,
14626 + mpls_fec * fec, ldp_attr * r_attr, ldp_attr * s_attr);
14628 +extern void abort2attr(mplsLdpLblAbortMsg_t * abrt, ldp_attr * a,
14629 + uint32_t flag);
14631 +#endif
14632 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_label_mapping.c quagga-mpls/ldpd/ldp_label_mapping.c
14633 --- quagga/ldpd/ldp_label_mapping.c 1969-12-31 18:00:00.000000000 -0600
14634 +++ quagga-mpls/ldpd/ldp_label_mapping.c 2006-10-19 01:31:18.000000000 -0500
14635 @@ -0,0 +1,1155 @@
14638 + * Copyright (C) James R. Leu 2000
14639 + * jleu@mindspring.com
14641 + * This software is covered under the LGPL, for more
14642 + * info check out http://www.gnu.org/copyleft/lgpl.html
14643 + */
14645 +#include "ldp_struct.h"
14646 +#include "ldp_session.h"
14647 +#include "ldp_attr.h"
14648 +#include "ldp_fec.h"
14649 +#include "ldp_mesg.h"
14650 +#include "ldp_notif.h"
14651 +#include "ldp_entity.h"
14652 +#include "ldp_inlabel.h"
14653 +#include "ldp_outlabel.h"
14654 +#include "ldp_nexthop.h"
14655 +#include "ldp_global.h"
14656 +#include "ldp_pdu_setup.h"
14657 +#include "ldp_label_rel_with.h"
14658 +#include "ldp_label_mapping.h"
14659 +#include "ldp_label_request.h"
14661 +#include "mpls_timer_impl.h"
14662 +#include "mpls_fib_impl.h"
14663 +#include "mpls_lock_impl.h"
14664 +#include "mpls_tree_impl.h"
14665 +#include "mpls_trace_impl.h"
14666 +#include "mpls_mm_impl.h"
14667 +#include "mpls_policy_impl.h"
14669 +#if MPLS_USE_LSR
14670 +#include "lsr_cfg.h"
14671 +#else
14672 +#include "mpls_mpls_impl.h"
14673 +#endif
14675 +mpls_return_enum ldp_label_mapping_with_xc(ldp_global * g, ldp_session * s,
14676 + ldp_fec * f, ldp_attr ** us_attr, ldp_attr * ds_attr)
14678 + mpls_return_enum result = MPLS_SUCCESS;
14679 + mpls_bool propogating = MPLS_BOOL_TRUE;
14680 + mpls_bool egress = MPLS_BOOL_FALSE;
14681 + mpls_bool egress_flag = MPLS_BOOL_FALSE;
14682 + mpls_bool created = MPLS_BOOL_FALSE;
14683 + ldp_nexthop *nh;
14685 + MPLS_ASSERT(us_attr);
14687 + nh = MPLS_LIST_HEAD(&f->nh_root);
14688 + while (nh) {
14689 + if (egress_flag == MPLS_BOOL_FALSE) {
14690 + egress_flag = mpls_policy_egress_check(g->user_data, &f->info, &nh->info);
14692 + nh = MPLS_LIST_NEXT(&f->nh_root, nh, _fec);
14695 + if (!(*us_attr)) {
14696 + if (!((*us_attr) = ldp_attr_create(g, &f->info))) {
14697 + return MPLS_FAILURE;
14699 + MPLS_REFCNT_HOLD((*us_attr));
14700 + created = MPLS_BOOL_TRUE;
14702 + if ((!ds_attr) && (egress_flag == MPLS_BOOL_TRUE)) {
14703 + propogating = MPLS_BOOL_FALSE;
14704 + egress = MPLS_BOOL_TRUE;
14707 + Prepare_Label_Mapping_Attributes(g, s, &f->info, ds_attr, (*us_attr),
14708 + propogating, MPLS_BOOL_TRUE, egress);
14710 + result = ldp_label_mapping_send(g, s, f, (*us_attr), ds_attr);
14711 + if (result != MPLS_SUCCESS) {
14712 + if (created == MPLS_BOOL_TRUE) {
14713 + /* this should result in it being deleted, since we're
14714 + * the only one who should be holding a ref
14715 + */
14716 + MPLS_REFCNT_RELEASE2(g, (*us_attr), ldp_attr_delete);
14718 + return result;
14721 + if (created == MPLS_BOOL_TRUE) {
14722 + result = ldp_attr_insert_upstream2(g, s, (*us_attr), f);
14723 + /* now that it is in the tree (supposedly) we can safely
14724 + * release our ref, if it is not in the tree, then this should
14725 + * result in it beig deleted
14726 + */
14727 + MPLS_REFCNT_RELEASE2(g, (*us_attr), ldp_attr_delete);
14728 + if (result != MPLS_SUCCESS) {
14729 + return result;
14733 + /*
14734 + * If we have a downstream mapping (not neccessarily installed) and
14735 + * the downstream and upstream session are not the same....
14736 + */
14737 + if (ds_attr && ((*us_attr)->session->index != ds_attr->session->index)) {
14738 + /* then link the attra */
14739 + ldp_attr_add_us2ds((*us_attr), ds_attr);
14741 + /* if we just created the upstream, and we have install the
14742 + * downstream, then cross connect them */
14743 + if ((created == MPLS_BOOL_TRUE) && ds_attr->outlabel) {
14745 + if ((*us_attr)->inlabel->outlabel) {
14746 + /*
14747 + * if we use an existing upstream mapping (in ldp_label_mapping_send())
14748 + * the inlabel will already be be connected to an outlabel;
14749 + */
14750 + MPLS_ASSERT((*us_attr)->inlabel->outlabel == ds_attr->outlabel);
14751 + } else {
14752 + LDP_TRACE_LOG(g->user_data,MPLS_TRACE_STATE_ALL,LDP_TRACE_FLAG_BINDING,
14753 + "Cross Connect Added for %08x/%d from %s -> %s\n",
14754 + f->info.u.prefix.network.u.ipv4, f->info.u.prefix.length,
14755 + (*us_attr)->session->session_name, ds_attr->session->session_name);
14757 + result = ldp_inlabel_add_outlabel(g,(*us_attr)->inlabel,
14758 + ds_attr->outlabel);
14759 + if (result != MPLS_SUCCESS) {
14760 + return result;
14765 + return MPLS_SUCCESS;
14768 +ldp_session *ldp_get_next_hop_session_for_fec2(ldp_fec * f, ldp_nexthop *nh) {
14769 + ldp_session *session = NULL;
14770 + /*
14771 + * find the info about the next hop for this FEC
14772 + */
14773 + if (nh->addr && nh->addr->session) {
14774 + session = nh->addr->session;
14775 + } else if (nh->iff && nh->iff->is_p2p == MPLS_BOOL_TRUE &&
14776 + nh->iff->entity) {
14777 + ldp_adj *adj = MPLS_LIST_HEAD(&nh->iff->entity->adj_root);
14778 + session = adj ? adj->session : NULL;
14780 + return session;
14783 +mpls_return_enum ldp_get_next_hop_session_for_fec(ldp_global * g,
14784 + mpls_fec * fec, mpls_nexthop *nh, ldp_session ** next_hop_session)
14786 + ldp_fec *f = NULL;
14787 + ldp_nexthop *n = NULL;
14789 + MPLS_ASSERT(next_hop_session);
14791 + if (!(f = ldp_fec_find(g, fec))) {
14792 + return MPLS_NO_ROUTE;
14795 + if (!(n = ldp_fec_nexthop_find(f, nh))) {
14796 + return MPLS_NO_ROUTE;
14799 + *next_hop_session = ldp_get_next_hop_session_for_fec2(f,n);
14800 + return (*next_hop_session) ? MPLS_SUCCESS : MPLS_FAILURE;
14803 +mpls_return_enum Check_Received_Attributes(ldp_global * g, ldp_session * s,
14804 + ldp_attr * r_attr, uint16_t type)
14806 + int count = 0;
14807 + int i;
14809 + if (!r_attr->hopCountTlvExists) { /* CRa.1 */
14810 + goto Check_Received_Attributes_5;
14813 + if (r_attr->hopCountTlv.hcValue >= s->cfg_hop_count_limit) { /* CRa.2 */
14814 + LDP_PRINT(g->user_data, "CRa.2\n");
14815 + goto Check_Received_Attributes_6;
14818 + if (!r_attr->pathVecTlvExists) { /* CRa.3 */
14819 + goto Check_Received_Attributes_5;
14822 + for (i = 0; i < MPLS_MAXHOPSNUMBER; i++) { /* CRa.4 */
14823 + if (r_attr->pathVecTlv.lsrId[i]) {
14824 + count++;
14825 + if (r_attr->pathVecTlv.lsrId[i] == g->lsr_identifier.u.ipv4) {
14826 + goto Check_Received_Attributes_6;
14827 + LDP_PRINT(g->user_data, "CRa.4a\n");
14829 + if (count > s->oper_path_vector_limit) {
14830 + goto Check_Received_Attributes_6;
14831 + LDP_PRINT(g->user_data, "CRa.4b\n");
14836 +Check_Received_Attributes_5:
14837 + return MPLS_SUCCESS;
14839 +Check_Received_Attributes_6:
14840 + if (type != MPLS_LBLMAP_MSGTYPE) {
14841 + ldp_notif_send(g, s, r_attr, LDP_NOTIF_LOOP_DETECTED); /* CRa.7 */
14843 + return MPLS_FAILURE; /* CRa.8 */
14846 +void Prepare_Label_Mapping_Attributes(ldp_global * g, ldp_session * s,
14847 + mpls_fec * fec, ldp_attr * r_attr, ldp_attr * s_attr, mpls_bool propogating,
14848 + mpls_bool already, mpls_bool egress)
14850 + ldp_attr dummy;
14851 + int i;
14853 + /* NOTE: PMpA.21 is the end of the procedure (ie return) */
14854 + /* this function uses goto quite extensivly for a REASON!! */
14855 + /* Check Appedix A of the LDP draft */
14857 + LDP_ENTER(g->user_data, "Prepare_Label_Mapping_Attributes");
14859 + if (!r_attr) {
14860 + memset(&dummy, 0, sizeof(ldp_attr));
14861 + mpls_fec2fec_tlv(fec, &dummy.fecTlv, 0);
14862 + dummy.fecTlvExists = 1;
14863 + dummy.fecTlv.numberFecElements = 1;
14864 + r_attr = &dummy;
14867 + if (!(s->oper_loop_detection == LDP_LOOP_HOPCOUNT ||
14868 + s->oper_loop_detection == LDP_LOOP_HOPCOUNT_PATHVECTOR ||
14869 + r_attr->hopCountTlvExists)) { /* PMpA.1 */
14870 + LDP_EXIT(g->user_data, "Prepare_Label_Mapping_Attributes");
14871 + return;
14874 + if (egress) {/* PMpA.2 */
14875 + /* I'm egress (for now) */
14876 + s_attr->hopCountTlvExists = 1;
14877 + s_attr->hopCountTlv.hcValue = 1; /* PMpA.3 */
14878 + LDP_EXIT(g->user_data, "Prepare_Label_Mapping_Attributes");
14879 + return;
14882 + if (!(r_attr->hopCountTlvExists)) { /* PMpA.4 */
14883 + goto Prepare_Label_Mapping_Attributes_8;
14886 + if (!(g->ttl_less_domain == MPLS_BOOL_TRUE &&
14887 + s->cfg_remote_in_ttl_less_domain == MPLS_BOOL_TRUE)) { /* PMpA.5 */
14888 + goto Prepare_Label_Mapping_Attributes_7;
14891 + s_attr->hopCountTlvExists = 1;
14892 + s_attr->hopCountTlv.hcValue = 1; /* PMpA.6 */
14893 + goto Prepare_Label_Mapping_Attributes_9;
14895 +Prepare_Label_Mapping_Attributes_7:
14896 + s_attr->hopCountTlvExists = 1;
14897 + s_attr->hopCountTlv.hcValue = (r_attr->hopCountTlv.hcValue) ?
14898 + (r_attr->hopCountTlv.hcValue + 1) : 0;
14899 + goto Prepare_Label_Mapping_Attributes_9;
14901 +Prepare_Label_Mapping_Attributes_8:
14902 + s_attr->hopCountTlvExists = 1;
14903 + s_attr->hopCountTlv.hcValue = 0;
14905 +Prepare_Label_Mapping_Attributes_9:
14906 + if (s->oper_loop_detection == LDP_LOOP_NONE) {
14907 + LDP_EXIT(g->user_data, "Prepare_Label_Mapping_Attributes");
14908 + return;
14911 + if (r_attr->pathVecTlvExists) { /* PMpA.10 */
14912 + goto Prepare_Label_Mapping_Attributes_19;
14915 + if (propogating == MPLS_BOOL_FALSE) { /* PMpA.11 */
14916 + goto Prepare_Label_Mapping_Attributes_20;
14919 + if (g->label_merge != MPLS_BOOL_TRUE) { /* PMpA.12 */
14920 + goto Prepare_Label_Mapping_Attributes_14;
14923 + if (already == MPLS_BOOL_FALSE) { /* PMpA.13 */
14924 + goto Prepare_Label_Mapping_Attributes_20;
14927 +Prepare_Label_Mapping_Attributes_14:
14928 + if (!r_attr->hopCountTlvExists) {
14929 + LDP_EXIT(g->user_data, "Prepare_Label_Mapping_Attributes");
14930 + return;
14933 + if (r_attr->hopCountTlv.hcValue == 0) { /* PMpA.15 */
14934 + goto Prepare_Label_Mapping_Attributes_20;
14937 + if (already == MPLS_BOOL_FALSE) { /* PMpA.16 */
14938 + LDP_EXIT(g->user_data, "Prepare_Label_Mapping_Attributes");
14939 + return;
14942 + /* r_attr contain PrevHopCount _IF_ we had one */
14943 + LDP_EXIT(g->user_data, "Prepare_Label_Mapping_Attributes");
14944 + return; /* PMpA.17 */
14946 + if (r_attr->hopCountTlv.hcValue != 0) { /* PMpA.18 */
14947 + LDP_EXIT(g->user_data, "Prepare_Label_Mapping_Attributes");
14948 + return;
14951 +Prepare_Label_Mapping_Attributes_19:
14952 + s_attr->pathVecTlvExists = 1;
14953 + s_attr->pathVecTlv.lsrId[0] = g->lsr_identifier.u.ipv4;
14954 + for (i = 1; i < (MPLS_MAXHOPSNUMBER - 1); i++) {
14955 + if (r_attr->pathVecTlv.lsrId[i - 1]) {
14956 + s_attr->pathVecTlv.lsrId[0] = r_attr->pathVecTlv.lsrId[i - 1];
14960 + LDP_EXIT(g->user_data, "Prepare_Label_Mapping_Attributes");
14961 + return;
14963 +Prepare_Label_Mapping_Attributes_20:
14964 + s_attr->pathVecTlvExists = 1;
14965 + s_attr->pathVecTlv.lsrId[0] = g->lsr_identifier.u.ipv4;
14967 + LDP_EXIT(g->user_data, "Prepare_Label_Mapping_Attributes");
14968 + return;
14971 +void map2attr(mplsLdpLblMapMsg_t * map, ldp_attr * attr, uint32_t flag)
14973 + attr->msg_id = map->baseMsg.msgId;
14975 + if (map->fecTlvExists && flag & LDP_ATTR_FEC) {
14976 + memcpy(&attr->fecTlv, &map->fecTlv, sizeof(mplsLdpFecTlv_t));
14977 + attr->fecTlvExists = 1;
14979 + if (map->genLblTlvExists && flag & LDP_ATTR_LABEL) {
14980 + memcpy(&attr->genLblTlv, &map->genLblTlv, sizeof(mplsLdpGenLblTlv_t));
14981 + attr->genLblTlvExists = 1;
14982 + } else if (map->atmLblTlvExists && flag & LDP_ATTR_LABEL) {
14983 + memcpy(&attr->atmLblTlv, &map->atmLblTlv, sizeof(mplsLdpAtmLblTlv_t));
14984 + attr->atmLblTlvExists = 1;
14985 + } else if (map->frLblTlvExists && flag & LDP_ATTR_LABEL) {
14986 + memcpy(&attr->frLblTlv, &map->frLblTlv, sizeof(mplsLdpFrLblTlv_t));
14987 + attr->frLblTlvExists = 1;
14989 + if (map->hopCountTlvExists && flag & LDP_ATTR_HOPCOUNT) {
14990 + memcpy(&attr->hopCountTlv, &map->hopCountTlv, sizeof(mplsLdpHopTlv_t));
14991 + attr->hopCountTlvExists = 1;
14993 + if (map->pathVecTlvExists && flag & LDP_ATTR_PATH) {
14994 + memcpy(&attr->pathVecTlv, &map->pathVecTlv, sizeof(mplsLdpPathTlv_t));
14995 + attr->pathVecTlvExists = 1;
14997 + if (map->lblMsgIdTlvExists && flag & LDP_ATTR_MSGID) {
14998 + memcpy(&attr->lblMsgIdTlv, &map->lblMsgIdTlv, sizeof(mplsLdpLblMsgIdTlv_t));
14999 + attr->lblMsgIdTlvExists = 1;
15001 + if (map->lspidTlvExists && flag & LDP_ATTR_LSPID) {
15002 + memcpy(&attr->lspidTlv, &map->lspidTlv, sizeof(mplsLdpLspIdTlv_t));
15003 + attr->lspidTlvExists = 1;
15005 + if (map->trafficTlvExists && flag & LDP_ATTR_TRAFFIC) {
15006 + memcpy(&attr->trafficTlv, &map->trafficTlv, sizeof(mplsLdpTrafficTlv_t));
15007 + attr->trafficTlvExists = 1;
15011 +void attr2map(ldp_attr * attr, mplsLdpLblMapMsg_t * map)
15013 + if (attr->fecTlvExists) {
15014 + memcpy(&map->fecTlv, &attr->fecTlv, sizeof(mplsLdpFecTlv_t));
15015 + map->fecTlvExists = 1;
15017 + if (attr->genLblTlvExists) {
15018 + memcpy(&map->genLblTlv, &attr->genLblTlv, sizeof(mplsLdpGenLblTlv_t));
15019 + map->genLblTlvExists = 1;
15021 + if (attr->atmLblTlvExists) {
15022 + memcpy(&map->atmLblTlv, &attr->atmLblTlv, sizeof(mplsLdpAtmLblTlv_t));
15023 + map->atmLblTlvExists = 1;
15025 + if (attr->frLblTlvExists) {
15026 + memcpy(&map->frLblTlv, &attr->frLblTlv, sizeof(mplsLdpFrLblTlv_t));
15027 + map->frLblTlvExists = 1;
15029 + if (attr->hopCountTlvExists) {
15030 + memcpy(&map->hopCountTlv, &attr->hopCountTlv, sizeof(mplsLdpHopTlv_t));
15031 + map->hopCountTlvExists = 1;
15033 + if (attr->pathVecTlvExists) {
15034 + memcpy(&map->pathVecTlv, &attr->pathVecTlv, sizeof(mplsLdpPathTlv_t));
15035 + map->pathVecTlvExists = 1;
15037 + if (attr->lblMsgIdTlvExists) {
15038 + memcpy(&map->lblMsgIdTlv, &attr->lblMsgIdTlv, sizeof(mplsLdpLblMsgIdTlv_t));
15039 + map->lblMsgIdTlvExists = 1;
15041 + if (attr->lspidTlvExists) {
15042 + memcpy(&map->lspidTlv, &attr->lspidTlv, sizeof(mplsLdpLspIdTlv_t));
15043 + map->lspidTlvExists = 1;
15045 + if (attr->trafficTlvExists) {
15046 + memcpy(&map->trafficTlv, &attr->trafficTlv, sizeof(mplsLdpTrafficTlv_t));
15047 + map->trafficTlvExists = 1;
15051 +void ldp_label_mapping_initial_callback(mpls_timer_handle timer, void *extra,
15052 + mpls_cfg_handle handle)
15054 + ldp_session *s = (ldp_session *) extra;
15055 + ldp_global *g = (ldp_global*)handle;
15056 + ldp_attr *ds_attr = NULL;
15057 + ldp_attr *us_attr = NULL;
15058 + ldp_session *nh_session = NULL;
15059 + mpls_bool done = MPLS_BOOL_FALSE;
15060 + ldp_fec *f;
15061 + ldp_nexthop *nh;
15063 + LDP_ENTER(g->user_data, "ldp_label_mapping_initial_callback");
15065 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_TIMER,
15066 + "Initial Label Mapping fired: session(%d)\n", s->index);
15068 + mpls_lock_get(g->global_lock);
15070 + mpls_timer_stop(g->timer_handle, timer);
15072 + f = MPLS_LIST_HEAD(&g->fec);
15073 + while (f) {
15074 + nh = MPLS_LIST_HEAD(&f->nh_root);
15075 + while (nh) {
15076 + switch (f->info.type) {
15077 + case MPLS_FEC_PREFIX:
15078 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
15079 + LDP_TRACE_FLAG_ROUTE, "Processing prefix FEC: %08x/%d ",
15080 + f->info.u.prefix.network.u.ipv4, f->info.u.prefix.length);
15081 + break;
15082 + case MPLS_FEC_HOST:
15083 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
15084 + LDP_TRACE_FLAG_ROUTE, "Processing host FEC: %08x ",
15085 + f->info.u.host.u.ipv4);
15086 + break;
15087 + case MPLS_FEC_L2CC:
15088 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
15089 + LDP_TRACE_FLAG_ROUTE, "Processingu L2CC FEC: %d %d %d ",
15090 + f->info.u.l2cc.connection_id, f->info.u.l2cc.group_id,
15091 + f->info.u.l2cc.type);
15092 + break;
15093 + default:
15094 + MPLS_ASSERT(0);
15097 + if (nh->info.type & MPLS_NH_IP) {
15098 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
15099 + LDP_TRACE_FLAG_ROUTE, "via %08x\n", nh->addr->address.u.ipv4);
15101 + if (nh->info.type & MPLS_NH_IF && nh->iff) {
15102 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
15103 + LDP_TRACE_FLAG_ROUTE, "via %p\n", nh->iff->handle);
15106 + /* are we allowed to export this route from the rib */
15107 + if (mpls_policy_export_check(g->user_data, &f->info, &nh->info) ==
15108 + MPLS_BOOL_FALSE) {
15109 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
15110 + LDP_TRACE_FLAG_POLICY, "Rejected by export policy\n");
15111 + goto ldp_label_mapping_initial_callback_end_nh;
15114 + /* have we already sent a mapping for this fec to the new session? */
15115 + if ((us_attr = ldp_attr_find_upstream_state2(g, s, f,
15116 + LDP_LSP_STATE_MAP_SENT))) {
15117 + /* no need to sent another mapping */
15118 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
15119 + LDP_TRACE_FLAG_ROUTE, "Already sent this FEC to session %d\n",
15120 + s->index);
15121 + goto ldp_label_mapping_initial_callback_end_nh;
15124 + if (!(nh_session = ldp_get_next_hop_session_for_fec2(f,nh))) {
15125 + ds_attr = NULL;
15126 + } else {
15127 + if (nh_session->index == s->index) {
15128 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
15129 + LDP_TRACE_FLAG_ROUTE, "Nexthop session(%d) == session(%d)\n",
15130 + nh_session->index, s->index);
15131 + goto ldp_label_mapping_initial_callback_end_nh;
15133 + ds_attr = ldp_attr_find_downstream_state2(g, nh_session, f,
15134 + LDP_LSP_STATE_MAP_RECV);
15137 + if ((g->label_merge != MPLS_BOOL_TRUE) &&
15138 + ldp_attr_num_us2ds(ds_attr)) {
15139 + /* we have a ds label, but can't use it */
15140 + ds_attr = NULL;
15143 + us_attr = NULL;
15144 + if (ds_attr) {
15145 + /* we can use it, merge on baby */
15146 + ldp_label_mapping_with_xc(g, s, f, &us_attr, ds_attr);
15147 + } else {
15148 + /* we don't have a ds label */
15150 + /* we will be egress? */
15151 + if (g->lsp_control_mode == LDP_CONTROL_ORDERED) {
15152 + if (mpls_policy_egress_check(g->user_data, &f->info,
15153 + &nh->info) == MPLS_BOOL_TRUE) {
15154 + ldp_label_mapping_with_xc(g, s, f, &us_attr, NULL);
15156 + } else {
15157 + ldp_label_mapping_with_xc(g, s, f, &us_attr, NULL);
15160 +ldp_label_mapping_initial_callback_end_nh:
15161 + nh = MPLS_LIST_NEXT(&f->nh_root, nh, _fec);
15163 + f = MPLS_LIST_NEXT(&g->fec, f, _global);
15165 + done = MPLS_BOOL_TRUE;
15167 + if (done == MPLS_BOOL_TRUE) {
15168 + mpls_timer_delete(g->timer_handle, timer);
15169 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
15170 + s->initial_distribution_timer = (mpls_timer_handle) 0;
15171 + } else {
15172 + mpls_timer_start(g->timer_handle, timer, MPLS_TIMER_ONESHOT);
15173 + /* need to mark the session with where it left off */
15176 + mpls_lock_release(g->global_lock);
15178 + LDP_EXIT(g->user_data, "ldp_label_mapping_initial_callback");
15181 +mpls_return_enum ldp_label_mapping_send(ldp_global * g, ldp_session * s,
15182 + ldp_fec *f, ldp_attr * us_attr, ldp_attr * ds_attr)
15184 + ldp_inlabel *in = NULL;
15185 + ldp_attr *us_temp, *existing = NULL;
15187 + LDP_ENTER(g->user_data, "ldp_label_mapping_send");
15188 + MPLS_ASSERT(us_attr);
15190 +#if 0
15191 + /*
15192 + * before we can enable this, inlabels need to keep track of all of
15193 + * the attr that link to it. Then when running in DU independent mode we
15194 + * can correctly attach the us and ds attrs involved when propogating a
15195 + * new mapping for a FEC we've already distributed labels for
15196 + */
15197 + existing = ldp_attr_find_upstream_map_in_labelspace(f, s->cfg_label_space);
15198 +#endif
15200 + if (existing) {
15201 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_BINDING,
15202 + "Using an existing label\n");
15203 + in = existing->inlabel;
15204 + ldp_attr_add_inlabel(g, us_attr, in);
15205 + } else {
15206 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_BINDING,
15207 + "Generating a label\n");
15208 + in = ldp_inlabel_create_complete(g, s, us_attr);
15211 + if (!in) { /* SL.1-3 */
15212 + goto Send_Label_9;
15215 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_BINDING,
15216 + "In Label Added\n");
15218 + us_attr->state = LDP_LSP_STATE_MAP_SENT;
15220 + us_attr->msg_id = g->message_identifier;
15221 + ldp_label_mapping_prepare_msg(s->tx_message, g->message_identifier++,
15222 + us_attr);
15224 + if (ldp_mesg_send_tcp(g, s, s->tx_message) != MPLS_SUCCESS) { /* SL.4 */
15225 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_ERROR,
15226 + "Failed sending Label Mapping to %s\n",
15227 + s->session_name);
15228 + goto ldp_label_mapping_send_error;
15231 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_LABEL,
15232 + "Label Mapping Sent to %s for %08x/%d\n",
15233 + s->session_name,
15234 + us_attr->fecTlv.fecElArray[0].addressEl.address,
15235 + us_attr->fecTlv.fecElArray[0].addressEl.preLen);
15237 + us_attr->state = LDP_LSP_STATE_MAP_SENT; /* SL.6,7 */
15239 + LDP_EXIT(g->user_data, "ldp_label_mapping_send");
15240 + return MPLS_SUCCESS; /* SL.8 */
15242 +Send_Label_9:
15243 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_STATE,
15244 + "No Label Resources\n");
15246 + while ((us_temp = ldp_attr_find_upstream_state2(g, s, us_attr->fec,
15247 + LDP_LSP_STATE_REQ_RECV)) != NULL) { /* SL.9 */
15248 + ldp_notif_send(g, s, us_temp, LDP_NOTIF_NO_LABEL_RESOURCES_AVAILABLE);
15249 + /* SL.10 */
15250 + s->no_label_resource_sent = MPLS_BOOL_TRUE; /* SL.12 */
15251 + us_temp->state = LDP_LSP_STATE_NO_LABEL_RESOURCE_SENT; /* SL.13 */
15254 + LDP_EXIT(g->user_data, "ldp_label_mapping_send");
15256 + return MPLS_SUCCESS;
15258 +ldp_label_mapping_send_error:
15260 + LDP_EXIT(g->user_data, "ldp_label_mapping_send-error");
15261 + return MPLS_FAILURE;
15264 +void ldp_label_mapping_prepare_msg(ldp_mesg * msg, uint32_t msgid,
15265 + ldp_attr * s_attr)
15267 + mplsLdpLblMapMsg_t *map = NULL;
15268 + int i;
15270 + MPLS_ASSERT(msg);
15272 + ldp_mesg_prepare(msg, MPLS_LBLMAP_MSGTYPE, msgid);
15273 + map = &msg->u.map;
15275 + if (s_attr->fecTlvExists) {
15276 + /* JLEU: only 1 FEC is allowed!! */
15277 + map->fecTlvExists = 1;
15278 + map->baseMsg.msgLength += setupFecTlv(&map->fecTlv);
15279 + map->baseMsg.msgLength += addFecElem2FecTlv(&map->fecTlv,
15280 + &s_attr->fecTlv.fecElArray[0]);
15282 + if (s_attr->genLblTlvExists) {
15283 + map->genLblTlvExists = 1;
15284 + map->baseMsg.msgLength += setupGenLblTlv(&map->genLblTlv,
15285 + s_attr->genLblTlv.label);
15287 + if (s_attr->atmLblTlvExists) {
15288 + map->atmLblTlvExists = 1;
15289 + map->baseMsg.msgLength += setupAtmLblTlv(&map->atmLblTlv, 0, 0,
15290 + s_attr->atmLblTlv.flags.flags.vpi, s_attr->atmLblTlv.vci);
15292 + if (s_attr->frLblTlvExists) {
15293 + map->frLblTlvExists = 1;
15294 + map->baseMsg.msgLength += setupFrLblTlv(&map->frLblTlv, 0,
15295 + s_attr->frLblTlv.flags.flags.len, s_attr->frLblTlv.flags.flags.dlci);
15297 + if (s_attr->hopCountTlvExists) {
15298 + map->hopCountTlvExists = 1;
15299 + map->baseMsg.msgLength += setupHopCountTlv(&map->hopCountTlv,
15300 + s_attr->hopCountTlv.hcValue);
15302 + if (s_attr->pathVecTlvExists) {
15303 + map->pathVecTlvExists = 1;
15304 + map->baseMsg.msgLength += setupPathTlv(&map->pathVecTlv);
15305 + for (i = 0; i < MPLS_MAXHOPSNUMBER; i++) {
15306 + if (s_attr->pathVecTlv.lsrId[i]) {
15307 + map->baseMsg.msgLength += addLsrId2PathTlv(&map->pathVecTlv,
15308 + s_attr->pathVecTlv.lsrId[i]);
15312 +#if 0
15313 + if (s_attr->lblMsgIdTlvExists) {
15315 + if (s_attr->lspidTlvExists) {
15317 + if (s_attr->trafficTlvExists) {
15319 +#endif
15322 +mpls_return_enum ldp_label_mapping_process(ldp_global * g, ldp_session * s,
15323 + ldp_adj * a, ldp_entity * e, ldp_attr * r_attr, ldp_fec * f)
15325 + mpls_return_enum retval = MPLS_SUCCESS;
15326 + ldp_session *peer = NULL;
15327 + ldp_attr_list *us_list = NULL;
15328 + ldp_attr_list *ds_list = NULL;
15329 + ldp_attr *ds_attr = NULL;
15330 + ldp_attr *ds_temp = NULL;
15331 + ldp_attr *us_attr = NULL;
15332 + ldp_attr *us_temp = NULL;
15333 + ldp_attr dumb_attr;
15334 + ldp_nexthop *nh = NULL;
15336 + ldp_outlabel *out = NULL;
15337 + mpls_bool requested = MPLS_BOOL_FALSE;
15338 + ldp_attr *existing = NULL;
15339 + mpls_bool need_request = MPLS_BOOL_FALSE;
15341 + LDP_ENTER(g->user_data, "ldp_label_mapping_process");
15343 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
15344 + "Label Mapping Recv from %s for %08x/%d\n",
15345 + s->session_name,
15346 + r_attr->fecTlv.fecElArray[0].addressEl.address,
15347 + r_attr->fecTlv.fecElArray[0].addressEl.preLen);
15349 + if ((ds_attr = ldp_attr_find_downstream_state2(g, s, f,
15350 + LDP_LSP_STATE_REQ_SENT)) != NULL) { /* LMp.1 */
15351 + /* just remove the req from the tree, we will use the r_attr sent to us */
15352 + ldp_attr_delete_downstream(g, s, ds_attr);
15353 + requested = MPLS_BOOL_TRUE;
15354 + } else {
15355 + requested = MPLS_BOOL_FALSE;
15358 + ds_attr = r_attr;
15359 + ds_attr->state = LDP_LSP_STATE_MAP_RECV; /* LMp.2 */
15361 + /*
15362 + * ds_attr is the mapping we will keep and is NOT in the tree, unless
15363 + * it is an update mapping ...
15364 + */
15365 + if (Check_Received_Attributes(g, s, ds_attr, MPLS_LBLMAP_MSGTYPE) ==
15366 + MPLS_SUCCESS) { /* LMp.3 */
15367 + goto LMp_9;
15370 + /*
15371 + * A loop was detected
15372 + */
15373 + if ((ds_list = ldp_attr_find_downstream_all2(g, s, f))) {
15374 + ds_temp = MPLS_LIST_HEAD(ds_list);
15375 + /*
15376 + * check all the labels this session has received from "s" for "fec"
15377 + * do we have a duplicat?
15378 + */
15379 + while (ds_temp) {
15380 + if ((ds_temp->state == LDP_LSP_STATE_MAP_RECV) && /* LMp.4 */
15381 + ldp_attr_is_equal(ds_temp, ds_attr, LDP_ATTR_LABEL) == /* LMp.5 */
15382 + MPLS_BOOL_TRUE) {
15383 + /* remove record of the label and remove it switching */
15384 + ldp_attr_remove_complete(g, ds_temp, MPLS_BOOL_TRUE); /* LMp.6,7 */
15385 + /*
15386 + * I think this is supposed to be 32 NOT 33, we need to release
15387 + * it don't we?
15388 + */
15389 + goto LMp_33;
15391 + ds_temp = MPLS_LIST_NEXT(ds_list, ds_temp, _fs);
15395 + LDP_PRINT(g->user_data, "Receive_Label_Map_8: send release");
15396 + if (ldp_label_release_send(g, s, ds_attr, LDP_NOTIF_LOOP_DETECTED) !=
15397 + MPLS_SUCCESS) { /* LMp.8 */
15398 + retval = MPLS_FAILURE;
15400 + goto LMp_33;
15402 +LMp_9:
15403 + /*
15404 + * No Loop Detected
15405 + */
15406 + ds_temp = ldp_attr_find_downstream_state2(g, s, f, LDP_LSP_STATE_MAP_RECV);
15407 + if (requested == MPLS_BOOL_TRUE ||
15408 + g->label_merge == MPLS_BOOL_FALSE || !ds_temp) {
15409 + /* !merging then this is always a new LSP
15410 + * merging w/o a recv'd mapping is a new LSP
15411 + * this check comes from Note 6
15412 + */
15413 + goto LMp_11;
15416 + /* searching all recv'd attrs for matched mappings,
15417 + * stop after finding 1st match
15418 + */
15419 + if ((ds_list = ldp_attr_find_downstream_all2(g, s, f))) {
15420 + ds_temp = MPLS_LIST_HEAD(ds_list);
15421 + while (ds_temp) {
15422 + if (ds_temp->state == LDP_LSP_STATE_MAP_RECV) { /* LMp.9 */
15423 + if (ldp_attr_is_equal(ds_attr, ds_temp, LDP_ATTR_LABEL) ==
15424 + MPLS_BOOL_TRUE) { /* LMp.10 */
15425 + /*
15426 + * this mapping matches an existing mapping, but it
15427 + * could contain updated attributes
15428 + */
15429 + existing = ds_temp;
15430 + break;
15431 + } else {
15432 + /*
15433 + * we have been given another label for the same FEC and we
15434 + * didn't request it, release it
15435 + */
15436 + LDP_PRINT(g->user_data, "LMp.10 dup without req\n");
15437 + goto LMp_32;
15440 + ds_temp = MPLS_LIST_NEXT(ds_list, ds_temp, _fs);
15443 + if (existing) {
15444 + ldp_attr2ldp_attr(ds_attr, existing, LDP_ATTR_HOPCOUNT | LDP_ATTR_PATH |
15445 + LDP_ATTR_MSGID | LDP_ATTR_LSPID | LDP_ATTR_TRAFFIC);
15446 + ds_attr = existing;
15447 + /*
15448 + * no need to free ds_attr, since it was not added to the tree it
15449 + * will be deleted when we exit ldp_label_mapping_process(), see
15450 + * ldp_state_process().
15451 + */
15453 + /*
15454 + * from this point on.... if this is an updated mapping then ds_attr
15455 + * is the existing mapping which has now been update, else ds_attr
15456 + * is the new mapping
15457 + */
15459 +LMp_11:
15460 + /*
15461 + * existing ONLY has a value for updated label mapping
15462 + */
15463 + nh = ldp_nexthop_for_fec_session(f,s); /* LMp.11 */
15465 + /*
15466 + * the following departs from the procedure, it allows for filtering
15467 + * of label mappings
15469 + * Are we configured to accept and INSTALL this mapping?
15470 + */
15471 + if (mpls_policy_import_check(g->user_data, &f->info, &nh->info) ==
15472 + MPLS_BOOL_FALSE) {
15473 + /*
15474 + * policy has rejected it, store it away
15475 + */
15476 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
15477 + "Label Mapping for %08x/%d from %s filtered by import policy\n",
15478 + r_attr->fecTlv.fecElArray[0].addressEl.address,
15479 + r_attr->fecTlv.fecElArray[0].addressEl.preLen, s->session_name);
15481 + if (existing) {
15482 + ds_attr->filtered = MPLS_BOOL_TRUE;
15483 + if (ds_attr->outlabel && ds_attr->outlabel->switching == MPLS_BOOL_TRUE) {
15484 + /* the mapping has been filtered, but the original wasn't? */
15485 + MPLS_ASSERT(0);
15487 + } else {
15488 + ds_attr->filtered = MPLS_BOOL_TRUE;
15489 + if (ldp_attr_insert_downstream(g, s, ds_attr) != MPLS_SUCCESS) {
15490 + retval = MPLS_FAILURE;
15493 + goto LMp_33;
15496 + if (!nh) { /* LMp.12 */
15497 + /*
15498 + * if we did not find a nh hop for this FEC that corresponded to the
15499 + * MsgSource then the MsgSource is not a nexthop for the FEC
15500 + */
15501 + if (g->label_retention_mode == LDP_RETENTION_CONSERVATIVE) { /* LMp.13C */
15502 + LDP_PRINT(g->user_data, "LMp.13C conservative\n");
15503 + goto LMp_32;
15506 + /*
15507 + * store it away
15508 + */
15509 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
15510 + "Session %s is not a valid nexthop for %08x/%d\n", s->session_name,
15511 + r_attr->fecTlv.fecElArray[0].addressEl.address,
15512 + r_attr->fecTlv.fecElArray[0].addressEl.preLen);
15514 + if (!existing) {
15515 + /* LMp.13L */
15516 + if (ldp_attr_insert_downstream(g, s, ds_attr) != MPLS_SUCCESS) {
15517 + retval = MPLS_FAILURE;
15520 + goto LMp_33;
15523 + /*
15524 + * this is slightly different form the procedure, we can still be
15525 + * transit for a FEC we are not configured to be ingress for.
15526 + * Either way we only need to do the "install for fwd/switching"
15527 + * only once. We could arrive here multiple times due to updates,
15528 + * only install it the first time
15529 + */
15530 + if ((!existing) || (!existing->outlabel)) {
15531 + /*
15532 + * we haven't installed it yet.
15533 + * Either new (!existing), or a result of a "Detect FEC Nexthop Change"
15534 + * and we had this mapping in our database (!existing->outlabel))
15535 + */
15537 + if (!(out = ldp_outlabel_create_complete(g, s, ds_attr, nh))) {
15538 + LDP_PRINT(g->user_data, "LMp.15 failure creating outlabel\n");
15539 + goto LMp_32;
15542 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_BINDING,
15543 + "Out Label Added\n");
15546 + /*
15547 + * are we configured to act as ingress for this FEC?
15548 + */
15549 + if (mpls_policy_ingress_check(g->user_data, &f->info, &nh->info) ==
15550 + MPLS_BOOL_TRUE) { /* LMp.14 */
15551 + /*
15552 + * yep, bind the label to the FEC
15553 + */
15554 + if (ds_attr->ingress != MPLS_BOOL_TRUE) {
15555 +#if MPLS_USE_LSR
15556 + lsr_ftn ftn;
15557 + ftn.outsegment_index = ds_attr->outlabel->info.handle;
15558 + memcpy(&ftn.fec, &f->info, sizeof(mpls_fec));
15559 + lsr_cfg_ftn_set2(g->lsr_handle, &ftn, LSR_CFG_ADD|LSR_FTN_CFG_FEC|
15560 + LSR_FTN_CFG_OUTSEGMENT);
15561 +#else
15562 + mpls_mpls_fec2out_add(g->mpls_handle, &f->info, &ds_attr->outlabel->info);
15563 +#endif
15564 + ds_attr->ingress = MPLS_BOOL_TRUE;
15565 + ds_attr->outlabel->merge_count++;
15566 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_BINDING,
15567 + "Acting as ingress for %08x/%d from %s\n",
15568 + r_attr->fecTlv.fecElArray[0].addressEl.address,
15569 + r_attr->fecTlv.fecElArray[0].addressEl.preLen, s->session_name);
15573 + /* create a set of attrs that we will fill and compare against
15574 + * if this mapping were to be propogate these are the attrs it would have
15575 + * by comparing what we did sent in the past to these, we con figure out
15576 + * if we need to send an updated mapping
15577 + */
15578 + memset(&dumb_attr, 0, sizeof(ldp_attr));
15579 + mpls_fec2fec_tlv(&f->info, &dumb_attr.fecTlv, 0);
15580 + dumb_attr.fecTlvExists = 1;
15581 + dumb_attr.fecTlv.numberFecElements = 1;
15583 + /*
15584 + * by definition (we received a label mapping that will be used) this
15585 + * LSR is _not_ the egress, so calculate a hop and path based on the
15586 + * mapping we received. We will compare this with mapping that have
15587 + * already been sent. If they differ, we will send an updated mapping
15588 + */
15589 + Prepare_Label_Mapping_Attributes(g, s, &f->info, ds_attr, &dumb_attr,
15590 + MPLS_BOOL_TRUE, MPLS_BOOL_TRUE, MPLS_BOOL_FALSE);
15592 + if (!existing) {
15593 + /*
15594 + * this is the first time we've seen this mapping, add it to the database.
15595 + * all future updates will modify this entry in place
15596 + */
15597 + /* LMp.16 */
15598 + if (ldp_attr_insert_downstream(g, s, ds_attr) != MPLS_SUCCESS) {
15599 + retval = MPLS_FAILURE;
15600 + goto LMp_33;
15604 + peer = MPLS_LIST_HEAD(&g->session);
15605 + while (peer) { /* LMp.17 */
15607 + /* can't send messages to non-operational sessions */
15608 + if (peer->state != LDP_STATE_OPERATIONAL) {
15609 + goto next_peer;
15612 + /*
15613 + * don't send the mapping to the session
15614 + * from which we recv'd the mapping
15615 + */
15616 + if (peer->index == s->index) {
15617 + goto next_peer;
15620 + /*
15621 + * it is just as easy to walk the list of all upstream attr for this
15622 + * peer as it is to the individual check to see if we have sent a
15623 + * label mapping for this FEC LSP
15624 + */
15626 + /* LMp.22 - 27 */
15627 + if ((us_list = ldp_attr_find_upstream_all2(g, peer, f))) {
15628 + us_temp = MPLS_LIST_HEAD(us_list);
15629 + while (us_temp) {
15630 + /*
15631 + * if we have sent a label mapping for the FEC and that label mapping
15632 + * was an done in independent mode or it is part of an LSP created
15633 + * due as part of an existing received label mapping
15634 + */
15635 + /* LMp.18 */
15636 + if (us_temp->state == LDP_LSP_STATE_MAP_SENT) {
15638 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
15639 + LDP_TRACE_FLAG_BINDING, "Already sent mapping for %08x/%d to %s\n",
15640 + r_attr->fecTlv.fecElArray[0].addressEl.address,
15641 + r_attr->fecTlv.fecElArray[0].addressEl.preLen, peer->session_name);
15643 + if ((!existing) || (existing->index == us_temp->ds_attr->index)) {
15645 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
15646 + LDP_TRACE_FLAG_BINDING, "Part of same LSP\n");
15648 + /* LMp.23 */
15649 + if (ldp_attr_is_equal(us_temp, &dumb_attr,
15650 + LDP_ATTR_HOPCOUNT | LDP_ATTR_PATH) != MPLS_BOOL_TRUE) {
15652 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
15653 + LDP_TRACE_FLAG_BINDING, "Propogating updated attrs\n");
15655 + /* send an updated label mapping */
15656 + if (ldp_label_mapping_with_xc(g, us_temp->session, f, &us_temp,
15657 + ds_attr) != MPLS_SUCCESS) { /* LMp.24-26 */
15658 + retval = MPLS_FAILURE;
15659 + goto LMp_33;
15664 + us_temp = MPLS_LIST_NEXT(us_list, us_temp, _fs);
15668 + if ((peer->oper_distribution_mode == LDP_DISTRIBUTION_UNSOLICITED) &&
15669 + (g->lsp_control_mode == LDP_CONTROL_ORDERED)) { /* LMp.19 */
15671 + /*
15672 + * if we're not merging and we have multiple ORDERED DU sessions,
15673 + * we will need to start requesting labels after we propogate the
15674 + * mapping to the first peer
15675 + */
15676 + if (need_request == MPLS_BOOL_TRUE) {
15677 + if (ldp_attr_find_downstream_state2(g, peer, f,
15678 + LDP_LSP_STATE_REQ_SENT) == NULL) {
15679 + /*
15680 + * we don't have a request for FEC to peer outstanding, make one
15681 + */
15682 + ds_temp = NULL;
15683 + if (ldp_label_request_for_xc(g, peer, &f->info, NULL, &ds_temp) !=
15684 + MPLS_SUCCESS) {
15685 + retval = MPLS_FAILURE;
15686 + goto LMp_33;
15689 + } else {
15690 + /*
15691 + * We're in DU more, either we're merging, or we're not merging and
15692 + * this is the first peer we're propogating this mapping to
15693 + */
15694 + /* LMp.20-21,30 */
15695 + us_attr = NULL;
15696 + if (ldp_label_mapping_with_xc(g, peer, f, &us_attr, ds_attr) !=
15697 + MPLS_SUCCESS) {
15698 + retval = MPLS_FAILURE;
15699 + goto LMp_33;
15701 + /*
15702 + * if we're not merging, we will need to request a label for
15703 + * the next DU peer
15704 + */
15705 + if (g->label_merge == MPLS_BOOL_FALSE) {
15706 + need_request = MPLS_BOOL_TRUE;
15711 + /* LMp.28 */
15712 + while ((us_temp = ldp_attr_find_upstream_state2(g, peer, f,
15713 + LDP_LSP_STATE_REQ_RECV))) {
15715 + if (peer->oper_distribution_mode == LDP_DISTRIBUTION_UNSOLICITED) {
15716 + if (need_request == MPLS_BOOL_TRUE) {
15717 + if (ldp_attr_find_downstream_state2(g, peer, f,
15718 + LDP_LSP_STATE_REQ_SENT) == NULL) {
15719 + /*
15720 + * we don't have a request for FEC to peer outstanding
15721 + */
15722 + ds_temp = NULL;
15723 + if (ldp_label_request_for_xc(g, peer, &f->info, us_temp,
15724 + &ds_temp) != MPLS_SUCCESS) {
15725 + retval = MPLS_FAILURE;
15726 + goto LMp_33;
15729 + } else {
15730 + if (ldp_label_mapping_with_xc(g, peer, f, &us_temp,
15731 + ds_attr) != MPLS_SUCCESS) {
15732 + retval = MPLS_FAILURE;
15733 + goto LMp_33;
15736 + } else {
15737 + if ((us_list = ldp_attr_find_upstream_all2(g, peer, f))) {
15738 + us_temp = MPLS_LIST_HEAD(ds_list);
15739 + while (us_temp) {
15740 + if (us_temp->state == LDP_LSP_STATE_REQ_RECV) {
15741 + if (need_request == MPLS_BOOL_TRUE) {
15742 + if (ldp_attr_find_downstream_state2(g, peer, f,
15743 + LDP_LSP_STATE_REQ_SENT) == NULL) {
15744 + /*
15745 + * we don't have a request for FEC to peer outstanding
15746 + */
15747 + ds_temp = NULL;
15748 + if (ldp_label_request_for_xc(g, peer, &f->info, us_temp,
15749 + &ds_temp) != MPLS_SUCCESS) {
15750 + retval = MPLS_FAILURE;
15751 + goto LMp_33;
15754 + } else {
15755 + if (ldp_label_mapping_with_xc(g, peer, f, &us_temp,
15756 + ds_attr) != MPLS_SUCCESS) {
15757 + retval = MPLS_FAILURE;
15758 + goto LMp_33;
15760 + /*
15761 + * if we're not merging, we will need to request a label for
15762 + * the next DU peer
15763 + */
15764 + if (g->label_merge == MPLS_BOOL_FALSE) {
15765 + need_request = MPLS_BOOL_TRUE;
15769 + us_temp = MPLS_LIST_NEXT(us_list, us_temp, _fs);
15775 + next_peer:
15776 + peer = MPLS_LIST_NEXT(&g->session, peer, _global);
15779 +LMp_33:
15780 + LDP_EXIT(g->user_data, "ldp_label_mapping_process");
15781 + return retval;
15783 +LMp_32:
15784 + LDP_PRINT(g->user_data, "Receive_Label_Map_32: send release");
15785 + if (ldp_label_release_send(g, s, ds_attr, LDP_NOTIF_NONE) != MPLS_SUCCESS) {
15786 + retval = MPLS_FAILURE;
15788 + LDP_EXIT(g->user_data, "ldp_label_mapping_process");
15789 + return retval;
15791 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_label_mapping.h quagga-mpls/ldpd/ldp_label_mapping.h
15792 --- quagga/ldpd/ldp_label_mapping.h 1969-12-31 18:00:00.000000000 -0600
15793 +++ quagga-mpls/ldpd/ldp_label_mapping.h 2006-08-09 21:56:15.000000000 -0500
15794 @@ -0,0 +1,44 @@
15797 + * Copyright (C) James R. Leu 2000
15798 + * jleu@mindspring.com
15800 + * This software is covered under the LGPL, for more
15801 + * info check out http://www.gnu.org/copyleft/lgpl.html
15802 + */
15804 +#ifndef _LDP_LABEL_MAPPING_H_
15805 +#define _LDP_LABEL_MAPPING_H_
15806 +#include "ldp_struct.h"
15808 +extern mpls_return_enum ldp_label_mapping_with_xc(ldp_global * g,
15809 + ldp_session * s, ldp_fec * fec, ldp_attr ** us_attr, ldp_attr * ds_attr);
15811 +extern void map2attr(mplsLdpLblMapMsg_t * map, ldp_attr * attr, uint32_t flag);
15812 +extern void attr2map(ldp_attr * attr, mplsLdpLblMapMsg_t * map);
15814 +extern void ldp_label_mapping_initial_callback(mpls_timer_handle timer,
15815 + void *extra, mpls_cfg_handle g);
15817 +extern void ldp_label_mapping_prepare_msg(ldp_mesg * msg, uint32_t msgid,
15818 + ldp_attr * s_attr);
15819 +extern mpls_return_enum ldp_label_mapping_send(ldp_global * g, ldp_session * s,
15820 + ldp_fec *f, ldp_attr * us_attr, ldp_attr * ds_attr);
15822 +extern mpls_return_enum ldp_label_mapping_process(ldp_global * g,
15823 + ldp_session * s, ldp_adj * a, ldp_entity * e, ldp_attr * r_attr,
15824 + ldp_fec * fec);
15826 +extern mpls_return_enum Check_Received_Attributes(ldp_global * g,
15827 + ldp_session * s, ldp_attr * r_attr, uint16_t type);
15829 +extern ldp_session *ldp_get_next_hop_session_for_fec2(ldp_fec *f,
15830 + ldp_nexthop *nh);
15831 +extern mpls_return_enum ldp_get_next_hop_session_for_fec(ldp_global * g,
15832 + mpls_fec * fec, mpls_nexthop *nh, ldp_session ** next_hop_session);
15834 +extern void Prepare_Label_Mapping_Attributes(ldp_global * g, ldp_session * s,
15835 + mpls_fec * fec, ldp_attr * r_attr, ldp_attr * s_attr, mpls_bool propogating,
15836 + mpls_bool already, mpls_bool egress);
15838 +#endif
15839 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_label_rel_with.c quagga-mpls/ldpd/ldp_label_rel_with.c
15840 --- quagga/ldpd/ldp_label_rel_with.c 1969-12-31 18:00:00.000000000 -0600
15841 +++ quagga-mpls/ldpd/ldp_label_rel_with.c 2006-10-16 22:34:21.000000000 -0500
15842 @@ -0,0 +1,294 @@
15845 + * Copyright (C) James R. Leu 2000
15846 + * jleu@mindspring.com
15848 + * This software is covered under the LGPL, for more
15849 + * info check out http://www.gnu.org/copyleft/lgpl.html
15850 + */
15852 +#include "ldp_struct.h"
15853 +#include "ldp_attr.h"
15854 +#include "ldp_session.h"
15855 +#include "ldp_global.h"
15856 +#include "ldp_inlabel.h"
15857 +#include "ldp_entity.h"
15858 +#include "ldp_outlabel.h"
15859 +#include "ldp_label_rel_with.h"
15860 +#include "ldp_nexthop.h"
15861 +#include "ldp_label_mapping.h"
15862 +#include "ldp_fec.h"
15863 +#include "ldp_mesg.h"
15864 +#include "ldp_pdu_setup.h"
15866 +#include "mpls_trace_impl.h"
15868 +mpls_bool rel_with2attr(mplsLdpLbl_W_R_Msg_t * rw, ldp_attr * attr)
15870 + mpls_bool retval = MPLS_BOOL_FALSE;
15872 + if (rw->fecTlvExists) {
15873 + memcpy(&attr->fecTlv, &rw->fecTlv, sizeof(mplsLdpFecTlv_t));
15874 + attr->fecTlvExists = 1;
15876 + if (rw->genLblTlvExists) {
15877 + retval = MPLS_BOOL_TRUE;
15878 + memcpy(&attr->genLblTlv, &rw->genLblTlv, sizeof(mplsLdpGenLblTlv_t));
15879 + attr->genLblTlvExists = 1;
15880 + } else if (rw->atmLblTlvExists) {
15881 + retval = MPLS_BOOL_TRUE;
15882 + memcpy(&attr->atmLblTlv, &rw->atmLblTlv, sizeof(mplsLdpAtmLblTlv_t));
15883 + attr->atmLblTlvExists = 1;
15884 + } else if (rw->frLblTlvExists) {
15885 + retval = MPLS_BOOL_TRUE;
15886 + memcpy(&attr->frLblTlv, &rw->frLblTlv, sizeof(mplsLdpFrLblTlv_t));
15887 + attr->frLblTlvExists = 1;
15889 + return retval;
15892 +void ldp_label_rel_with_prepare_msg(ldp_mesg * msg, uint32_t msgid,
15893 + ldp_attr * a, ldp_notif_status status, uint16_t type)
15895 + mplsLdpLbl_W_R_Msg_t *rw = NULL;
15897 + ldp_mesg_prepare(msg, type, msgid);
15898 + rw = &msg->u.release;
15899 + if (a->fecTlvExists) {
15900 + rw->fecTlvExists = 1;
15901 + rw->baseMsg.msgLength += setupFecTlv(&rw->fecTlv);
15902 + rw->baseMsg.msgLength += addFecElem2FecTlv(&rw->fecTlv,
15903 + &a->fecTlv.fecElArray[0]);
15905 + if (a->genLblTlvExists) {
15906 + rw->genLblTlvExists = 1;
15907 + rw->baseMsg.msgLength += setupGenLblTlv(&rw->genLblTlv, a->genLblTlv.label);
15909 + if (a->atmLblTlvExists) {
15910 + rw->atmLblTlvExists = 1;
15911 + rw->baseMsg.msgLength += setupAtmLblTlv(&rw->atmLblTlv, 0, 0,
15912 + a->atmLblTlv.flags.flags.vpi, a->atmLblTlv.vci);
15914 + if (a->frLblTlvExists) {
15915 + rw->frLblTlvExists = 1;
15916 + rw->baseMsg.msgLength += setupFrLblTlv(&rw->frLblTlv, 0,
15917 + a->frLblTlv.flags.flags.len, a->frLblTlv.flags.flags.dlci);
15919 + if (a->lspidTlvExists) {
15920 + rw->lspidTlvExists = 1;
15921 + rw->baseMsg.msgLength += setupLspidTlv(&rw->lspidTlv, 0,
15922 + a->lspidTlv.localCrlspId, a->lspidTlv.routerId);
15926 +mpls_return_enum ldp_label_rel_with_send(ldp_global * g, ldp_session * s,
15927 + ldp_attr * a, ldp_notif_status status, uint16_t type)
15929 + LDP_ENTER(g->user_data, "ldp_label_rel_with_send");
15931 + ldp_label_rel_with_prepare_msg(s->tx_message, g->message_identifier++, a,
15932 + status, type);
15934 + ldp_mesg_send_tcp(g, s, s->tx_message);
15936 + LDP_EXIT(g->user_data, "ldp_label_rel_with_send");
15938 + return MPLS_SUCCESS;
15941 +mpls_return_enum ldp_label_release_send(ldp_global * g, ldp_session * s,
15942 + ldp_attr * a, ldp_notif_status status)
15945 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_LABEL,
15946 + "Release Sent: session(%d)\n", s->index);
15948 + return ldp_label_rel_with_send(g, s, a, status, MPLS_LBLREL_MSGTYPE);
15951 +mpls_return_enum ldp_label_withdraw_send(ldp_global * g, ldp_session * s,
15952 + ldp_attr * us_attr, ldp_notif_status status)
15955 + us_attr->state = LDP_LSP_STATE_WITH_SENT;
15956 + if (ldp_label_rel_with_send(g, s, us_attr, status, MPLS_LBLWITH_MSGTYPE) ==
15957 + MPLS_FAILURE) {
15958 + return MPLS_FAILURE;
15961 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_LABEL,
15962 + "Withdraw Sent: session(%d)\n", s->index);
15964 + return MPLS_SUCCESS;
15967 +mpls_return_enum ldp_label_release_process(ldp_global * g, ldp_session * s,
15968 + ldp_adj * a, ldp_entity * e, ldp_attr * r_attr, ldp_fec * f)
15970 + mpls_bool label_exists = MPLS_BOOL_FALSE;
15971 + ldp_attr *us_attr = NULL;
15972 + ldp_attr *ds_attr = NULL;
15973 + mpls_return_enum retval = MPLS_SUCCESS;
15975 + LDP_ENTER(g->user_data, "ldp_label_release_process");
15977 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
15978 + "Release Recv from %s\n", s->session_name);
15980 + if (r_attr->genLblTlvExists || r_attr->atmLblTlvExists
15981 + || r_attr->frLblTlvExists) {
15982 + label_exists = MPLS_BOOL_TRUE;
15985 + if (f) {
15986 + /* LRl.1 is accomplished at LRl.10 */
15987 + us_attr = ldp_attr_find_upstream_state2(g, s, f, LDP_LSP_STATE_MAP_SENT);
15988 + if (!us_attr) {
15989 + us_attr =
15990 + ldp_attr_find_upstream_state2(g, s, f, LDP_LSP_STATE_WITH_SENT);
15991 + if (!us_attr) { /* LRl.2 */
15992 + goto LRl_13;
15994 + /* LRl.3 is accomplished at LRl.10 */
15997 + if (g->label_merge == MPLS_BOOL_FALSE) { /* LR1.4 */
15998 + goto LRl_6;
16000 + /* LR1.5 */
16001 + if (ldp_attr_find_upstream_state_any2(g, f, LDP_LSP_STATE_MAP_SENT)) {
16002 + goto LRl_10;
16005 + LRl_6:
16006 + /* we can only propogate a release to the downstream attached to
16007 + the upstream we found up top */
16008 + /* LRl.6,7 */
16009 + if (us_attr->ds_attr && us_attr->ds_attr->state == LDP_LSP_STATE_MAP_RECV) {
16010 + ds_attr = us_attr->ds_attr;
16011 + } else {
16012 + goto LRl_10;
16015 + if (g->propagate_release == MPLS_BOOL_FALSE) { /* LRl.8 */
16016 + goto LRl_10;
16019 + if (ldp_label_release_send(g, ds_attr->session, ds_attr,
16020 + LDP_NOTIF_NONE) != MPLS_SUCCESS) { /* LRl.9 */
16021 + retval = MPLS_FAILURE;
16023 + ldp_attr_remove_complete(g, ds_attr, MPLS_BOOL_FALSE);
16025 + LRl_10:
16026 + ldp_attr_remove_complete(g, us_attr, MPLS_BOOL_FALSE); /* LRl.10,11 */
16028 + } else {
16029 + LDP_PRINT(g->user_data, "No FEC in release, need to implement\n");
16030 + MPLS_ASSERT(0);
16033 +LRl_13:
16034 + LDP_EXIT(g->user_data, "ldp_label_release_process");
16035 + return retval;
16038 +mpls_return_enum ldp_label_withdraw_process(ldp_global * g, ldp_session * s,
16039 + ldp_adj * a, ldp_entity * e, ldp_attr * r_attr, ldp_fec * f)
16041 + mpls_bool label_exists = MPLS_BOOL_FALSE;
16042 + ldp_attr_list *ds_list = NULL;
16043 + ldp_attr *ds_attr = NULL;
16044 + ldp_attr *ds_temp = NULL;
16045 + ldp_attr *us_temp = NULL;
16046 + ldp_nexthop *nh = NULL;
16047 + mpls_return_enum retval = MPLS_SUCCESS;
16049 + LDP_ENTER(g->user_data, "ldp_label_withdraw_process");
16051 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
16052 + "Withdraw Recv for %s\n", s->session_name);
16054 + if (r_attr->genLblTlvExists || r_attr->atmLblTlvExists
16055 + || r_attr->frLblTlvExists) {
16056 + label_exists = MPLS_BOOL_TRUE;
16057 + } else {
16058 + MPLS_ASSERT(0);
16061 + if (f) {
16062 + if ((ds_list = ldp_attr_find_downstream_all2(g, s, f)) != NULL) {
16063 + ds_temp = MPLS_LIST_HEAD(ds_list);
16064 + while (ds_temp) {
16065 + if (ds_temp->state == LDP_LSP_STATE_MAP_RECV) { /* LWd.3 */
16066 + if (ldp_attr_is_equal(r_attr, ds_temp, LDP_ATTR_LABEL)) {
16067 + ds_attr = ds_temp;
16068 + break;
16071 + ds_temp = MPLS_LIST_NEXT(ds_list, ds_temp, _fs);
16075 + if (!ds_attr) {
16076 + retval = MPLS_FAILURE;
16077 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
16078 + "Withdraw Recv for a non-existant mapping from %s\n",s->session_name);
16079 + goto LWd_13;
16082 + /*
16083 + * we want to remove it from the tree, but not delete it yet
16084 + * so hold a refcnt, we will release that refcnt at the end, thus
16085 + * deleting it if no one else it holding a refcnt
16086 + */
16087 + MPLS_REFCNT_HOLD(ds_attr);
16088 + ldp_attr_remove_complete(g, ds_attr, MPLS_BOOL_FALSE); /* LWd.4 */
16090 + /* LWd.2 */
16091 + if (ldp_label_release_send(g, s, ds_attr, LDP_NOTIF_NONE) != MPLS_SUCCESS) {
16092 + retval = MPLS_FATAL;
16093 + goto LWd_13;
16096 + if (g->lsp_control_mode == LDP_CONTROL_ORDERED) { /* LWd.5 */
16097 + goto LWd_8;
16100 + if (s->oper_distribution_mode != LDP_DISTRIBUTION_ONDEMAND) { /* LWd.6 */
16101 + goto LWd_13;
16104 + MPLS_ASSERT((nh = ldp_nexthop_for_fec_session(f, s)));
16105 + retval = ldp_fec_process_add(g, f, nh, s); /* LWd.7 */
16106 + goto LWd_13;
16108 + LWd_8:
16109 + /* I can only propogate a label withdraw to the upstreams attached
16110 + to the downstream found above */
16112 + us_temp = MPLS_LIST_HEAD(&ds_attr->us_attr_root);
16113 + while (us_temp) {
16114 + if (us_temp->state == LDP_LSP_STATE_MAP_SENT) {
16115 + if (ldp_label_withdraw_send(g, us_temp->session, us_temp,
16116 + LDP_NOTIF_NONE) != MPLS_SUCCESS) { /* LWd.11 */
16117 + retval = MPLS_FATAL;
16118 + goto LWd_13;
16121 + us_temp = MPLS_LIST_NEXT(&ds_attr->us_attr_root, us_temp, _ds_attr);
16123 + } else {
16124 + /* JLEU: process wildcard FEC stuff here */
16125 + MPLS_ASSERT(0);
16128 +LWd_13:
16129 + if (ds_attr) {
16130 + MPLS_REFCNT_RELEASE2(g, ds_attr, ldp_attr_delete);
16133 + LDP_EXIT(g->user_data, "ldp_label_withdraw_process");
16135 + return retval;
16137 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_label_rel_with.h quagga-mpls/ldpd/ldp_label_rel_with.h
16138 --- quagga/ldpd/ldp_label_rel_with.h 1969-12-31 18:00:00.000000000 -0600
16139 +++ quagga-mpls/ldpd/ldp_label_rel_with.h 2006-08-09 21:56:10.000000000 -0500
16140 @@ -0,0 +1,27 @@
16143 + * Copyright (C) James R. Leu 2000
16144 + * jleu@mindspring.com
16146 + * This software is covered under the LGPL, for more
16147 + * info check out http://www.gnu.org/copyleft/lgpl.html
16148 + */
16150 +#ifndef _LDP_LABEL_RELEASE_H_
16151 +#define _LDP_LABEL_RELEASE_H_
16153 +extern mpls_return_enum ldp_label_release_send(ldp_global *, ldp_session *,
16154 + ldp_attr *, ldp_notif_status);
16155 +extern mpls_return_enum ldp_label_withdraw_send(ldp_global *, ldp_session *,
16156 + ldp_attr *, ldp_notif_status);
16157 +extern mpls_bool rel_with2attr(mplsLdpLbl_W_R_Msg_t * rw, ldp_attr * attr);
16158 +extern ldp_mesg *ldp_label_rel_with_create_msg(uint32_t msgid, ldp_attr * a,
16159 + ldp_notif_status status, uint16_t type);
16160 +extern mpls_return_enum ldp_label_release_process(ldp_global * g,
16161 + ldp_session * s, ldp_adj * a, ldp_entity * e, ldp_attr * r_attr,
16162 + ldp_fec * fec);
16163 +extern mpls_return_enum ldp_label_withdraw_process(ldp_global * g,
16164 + ldp_session * s, ldp_adj * a, ldp_entity * e, ldp_attr * r_attr,
16165 + ldp_fec * fec);
16167 +#endif
16168 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_label_request.c quagga-mpls/ldpd/ldp_label_request.c
16169 --- quagga/ldpd/ldp_label_request.c 1969-12-31 18:00:00.000000000 -0600
16170 +++ quagga-mpls/ldpd/ldp_label_request.c 2006-10-16 22:43:27.000000000 -0500
16171 @@ -0,0 +1,479 @@
16174 + * Copyright (C) James R. Leu 2000
16175 + * jleu@mindspring.com
16177 + * This software is covered under the LGPL, for more
16178 + * info check out http://www.gnu.org/copyleft/lgpl.html
16179 + */
16181 +#include "ldp_struct.h"
16182 +#include "ldp_attr.h"
16183 +#include "ldp_fec.h"
16184 +#include "ldp_mesg.h"
16185 +#include "ldp_pdu_setup.h"
16186 +#include "ldp_notif.h"
16187 +#include "ldp_session.h"
16188 +#include "ldp_entity.h"
16189 +#include "ldp_label_mapping.h"
16190 +#include "ldp_label_request.h"
16192 +#include "mpls_timer_impl.h"
16193 +#include "mpls_policy_impl.h"
16194 +#include "mpls_tree_impl.h"
16195 +#include "mpls_trace_impl.h"
16196 +#include "mpls_fib_impl.h"
16197 +#include "mpls_lock_impl.h"
16199 +mpls_return_enum ldp_label_request_for_xc(ldp_global * g, ldp_session * s,
16200 + mpls_fec * fec, ldp_attr * us_attr, ldp_attr ** ds_attr)
16203 + LDP_ENTER(g->user_data, "ldp_label_request_for_xc");
16205 + if (!(*ds_attr)) {
16206 + if (!((*ds_attr) = ldp_attr_create(g, fec))) {
16207 + return MPLS_FATAL;
16209 + MPLS_REFCNT_HOLD((*ds_attr));
16211 + Prepare_Label_Request_Attributes(g, s, fec, (*ds_attr), us_attr);
16212 + (*ds_attr)->state = LDP_LSP_STATE_REQ_SENT;
16213 + if (ldp_label_request_send(g, s, us_attr, ds_attr) != MPLS_SUCCESS) {
16214 + return MPLS_FAILURE;
16217 + LDP_EXIT(g->user_data, "ldp_label_request_for_xc");
16219 + return MPLS_SUCCESS;
16222 +void ldp_label_request_prepare_msg(ldp_mesg * msg, uint32_t msgid,
16223 + ldp_attr * s_attr)
16225 + mplsLdpLblReqMsg_t *req = NULL;
16226 + int i;
16228 + ldp_mesg_prepare(msg, MPLS_LBLREQ_MSGTYPE, msgid);
16229 + req = &msg->u.request;
16231 + if (s_attr->fecTlvExists) {
16232 + req->fecTlvExists = 1;
16233 + req->baseMsg.msgLength += setupFecTlv(&req->fecTlv);
16234 + req->baseMsg.msgLength += addFecElem2FecTlv(&req->fecTlv,
16235 + &s_attr->fecTlv.fecElArray[0]);
16237 + if (s_attr->hopCountTlvExists) {
16238 + req->hopCountTlvExists = 1;
16239 + req->baseMsg.msgLength += setupHopCountTlv(&req->hopCountTlv,
16240 + s_attr->hopCountTlv.hcValue);
16242 + if (s_attr->pathVecTlvExists) {
16243 + req->pathVecTlvExists = 1;
16244 + req->baseMsg.msgLength += setupPathTlv(&req->pathVecTlv);
16245 + for (i = 0; i < MPLS_MAXHOPSNUMBER; i++) {
16246 + if (s_attr->pathVecTlv.lsrId[i]) {
16247 + req->baseMsg.msgLength += addLsrId2PathTlv(&req->pathVecTlv,
16248 + s_attr->pathVecTlv.lsrId[i]);
16254 +mpls_return_enum ldp_label_request_send(ldp_global * g, ldp_session * s,
16255 + ldp_attr * us_attr, ldp_attr ** ds_attr)
16257 + ldp_attr *ds_temp;
16258 + mpls_fec fec;
16260 + LDP_ENTER(g->user_data, "ldp_label_request_send");
16261 + MPLS_ASSERT(ds_attr && *ds_attr);
16263 + fec_tlv2mpls_fec(&((*ds_attr)->fecTlv), 0, &fec);
16265 + if ((ds_temp = ldp_attr_find_downstream_state(g, s, &fec,
16266 + LDP_LSP_STATE_REQ_SENT)) != NULL) { /* SLRq.1 */
16268 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_LABEL,
16269 + "Label Request Send: request already pending(%d)\n", ds_temp->index);
16271 + ldp_attr_add_us2ds(us_attr, ds_temp);
16273 + /* we do not need the one passed in, but make sure that the caller
16274 + is using this one from here forth */
16275 + ldp_attr_remove_complete(g, *ds_attr, MPLS_BOOL_TRUE);
16276 + *ds_attr = ds_temp;
16277 + return MPLS_SUCCESS;
16280 + if (s->no_label_resource_recv == MPLS_BOOL_TRUE) { /* SLRq.2 */
16281 + goto ldp_label_request_send_error;
16284 + (*ds_attr)->msg_id = g->message_identifier++;
16285 + ldp_label_request_prepare_msg(s->tx_message, (*ds_attr)->msg_id, *ds_attr);
16287 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_LABEL,
16288 + "Label Request Sent: session(%d)\n", s->index);
16290 + if (ldp_mesg_send_tcp(g, s, s->tx_message) == MPLS_FAILURE) { /* SLRq.3 */
16291 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_ERROR,
16292 + "Label Request send failed\n");
16293 + goto ldp_label_request_send_error;
16296 + (*ds_attr)->state = LDP_LSP_STATE_REQ_SENT;
16297 + if (ldp_attr_insert_downstream(g, s, (*ds_attr)) == MPLS_FAILURE) { /* SLRq.4 */
16298 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_ERROR,
16299 + "Couldn't insert sent attributes in tree\n");
16300 + goto ldp_label_request_send_error;
16302 + if (us_attr) {
16303 + ldp_attr_add_us2ds(us_attr, *ds_attr);
16306 + LDP_EXIT(g->user_data, "ldp_label_request_send");
16308 + return MPLS_SUCCESS; /* SLRq.5 */
16310 +ldp_label_request_send_error:
16312 + LDP_PRINT(g->user_data, "SLRq.6\n");
16313 + (*ds_attr)->state = LDP_LSP_STATE_NO_LABEL_RESOURCE_SENT;
16314 + ldp_attr_insert_downstream(g, s, (*ds_attr)); /* SLRq.6 */
16316 + LDP_EXIT(g->user_data, "ldp_label_request_send-error");
16318 + return MPLS_FAILURE; /* SLRq.7 */
16321 +void req2attr(mplsLdpLblReqMsg_t * req, ldp_attr * attr, uint32_t flag)
16323 + attr->msg_id = req->baseMsg.msgId;
16325 + if (req->fecTlvExists && flag & LDP_ATTR_FEC) {
16326 + memcpy(&attr->fecTlv, &req->fecTlv, sizeof(mplsLdpFecTlv_t));
16327 + attr->fecTlvExists = 1;
16329 + if (req->hopCountTlvExists && flag & LDP_ATTR_HOPCOUNT) {
16330 + memcpy(&attr->hopCountTlv, &req->hopCountTlv, sizeof(mplsLdpHopTlv_t));
16331 + attr->hopCountTlvExists = 1;
16333 + if (req->pathVecTlvExists && flag & LDP_ATTR_PATH) {
16334 + memcpy(&attr->pathVecTlv, &req->pathVecTlv, sizeof(mplsLdpPathTlv_t));
16335 + attr->pathVecTlvExists = 1;
16337 + if (req->lblMsgIdTlvExists && flag & LDP_ATTR_MSGID) {
16338 + memcpy(&attr->lblMsgIdTlv, &req->lblMsgIdTlv, sizeof(mplsLdpLblMsgIdTlv_t));
16339 + attr->lblMsgIdTlvExists = 1;
16341 + if (req->lspidTlvExists && flag & LDP_ATTR_LSPID) {
16342 + memcpy(&attr->lspidTlv, &req->lspidTlv, sizeof(mplsLdpLspIdTlv_t));
16343 + attr->lspidTlvExists = 1;
16345 + if (req->trafficTlvExists && flag & LDP_ATTR_TRAFFIC) {
16346 + memcpy(&attr->trafficTlv, &req->trafficTlv, sizeof(mplsLdpTrafficTlv_t));
16347 + attr->trafficTlvExists = 1;
16351 +void ldp_label_request_initial_callback(mpls_timer_handle timer, void *extra,
16352 + mpls_cfg_handle handle)
16354 + ldp_session *s = (ldp_session *)extra;
16355 + ldp_global *g = (ldp_global*)handle;
16356 + ldp_nexthop *nh = NULL;
16357 + ldp_fec *f = NULL;
16359 + ldp_session *nh_session = NULL;
16360 + mpls_bool done = MPLS_BOOL_FALSE;
16362 + ldp_attr *attr = NULL;
16363 + ldp_fs *fs = NULL;
16364 + ldp_attr *ds_attr = NULL;
16366 + LDP_ENTER(g->user_data, "ldp_label_request_initial_callback");
16368 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_TIMER,
16369 + "Initial Label Request Callback fired: session(%d)\n", s->index);
16371 + mpls_lock_get(g->global_lock);
16373 + mpls_timer_stop(g->timer_handle, timer);
16375 + if ((f = MPLS_LIST_HEAD(&g->fec))) {
16376 + do {
16377 + if ((nh = MPLS_LIST_HEAD(&f->nh_root))) {
16378 + do {
16379 + switch (f->info.type) {
16380 + case MPLS_FEC_PREFIX:
16381 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
16382 + LDP_TRACE_FLAG_ROUTE, "Processing prefix FEC: %08x/%d ",
16383 + f->info.u.prefix.network.u.ipv4, f->info.u.prefix.length);
16384 + break;
16385 + case MPLS_FEC_HOST:
16386 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
16387 + LDP_TRACE_FLAG_ROUTE, "Processing host FEC: %08x ",
16388 + f->info.u.host.u.ipv4);
16389 + break;
16390 + case MPLS_FEC_L2CC:
16391 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
16392 + LDP_TRACE_FLAG_ROUTE, "Processing L2CC FEC: %d %d %d ",
16393 + f->info.u.l2cc.connection_id, f->info.u.l2cc.group_id,
16394 + f->info.u.l2cc.type);
16395 + break;
16396 + default:
16397 + MPLS_ASSERT(0);
16400 + if (nh->info.type & MPLS_NH_IP) {
16401 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
16402 + LDP_TRACE_FLAG_ROUTE, "via %08x\n", nh->addr->address.u.ipv4);
16404 + if (nh->info.type & MPLS_NH_IF) {
16405 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
16406 + LDP_TRACE_FLAG_ROUTE, "via %p\n", nh->iff->handle);
16409 + /* check to see if export policy allows us to 'see' this route */
16410 + if (mpls_policy_export_check(g->user_data, &f->info, &nh->info)
16411 + == MPLS_BOOL_FALSE) {
16412 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
16413 + LDP_TRACE_FLAG_DEBUG, "Rejected by export policy\n");
16414 + continue;
16417 + /* find the next hop session corresponding to this FEC */
16418 + nh_session = ldp_session_for_nexthop(nh);
16420 + /* do we have a valid next hop session, and is the nexp hop session
16421 + * this session? */
16422 + if ((!nh_session) || (nh_session->index != s->index)) {
16423 + continue;
16426 + /* have we already sent a label request to this peer for this FEC? */
16427 + if (ldp_attr_find_downstream_state(g, s, &f->info,
16428 + LDP_LSP_STATE_REQ_SENT)) {
16429 + continue;
16432 + /* clear out info from the last FEC */
16433 + ds_attr = NULL;
16435 + /* jleu: duplicate code from ldp_attr_find_upstream_state_any */
16436 + fs = MPLS_LIST_HEAD(&f->fs_root_us);
16437 + while (fs) {
16438 + attr = MPLS_LIST_HEAD(&fs->attr_root);
16439 + while (attr) {
16440 + if (attr->state == LDP_LSP_STATE_REQ_RECV ||
16441 + attr->state == LDP_LSP_STATE_MAP_SENT) {
16442 + if (!ds_attr) {
16443 + /* this is not neccessarily going to be XC'd to something */
16444 + ldp_label_request_for_xc(g, s, &f->info, attr, &ds_attr);
16447 + attr = MPLS_LIST_NEXT(&fs->attr_root, attr, _fs);
16449 + fs = MPLS_LIST_NEXT(&f->fs_root_us, fs, _fec);
16452 + if (!ds_attr) {
16453 + /*
16454 + * we did not find any received requests or sent mappings so
16455 + * send a request and xc it to nothing
16456 + */
16457 + ldp_label_request_for_xc(g, s, &f->info, NULL, &ds_attr);
16459 + } while ((nh = MPLS_LIST_NEXT(&f->nh_root, nh, _fec)));
16461 + } while ((f = MPLS_LIST_NEXT(&g->fec, f, _global)));
16462 + done = MPLS_BOOL_TRUE;
16465 + if (done == MPLS_BOOL_TRUE) {
16466 + mpls_timer_delete(g->timer_handle, timer);
16467 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
16468 + s->initial_distribution_timer = (mpls_timer_handle) 0;
16469 + } else {
16470 + mpls_timer_start(g->timer_handle, timer, MPLS_TIMER_ONESHOT);
16471 + /* need to mark the session with where it left off */
16474 + mpls_lock_release(g->global_lock);
16476 + LDP_EXIT(g->user_data, "ldp_label_request_initial_callback");
16479 +void Prepare_Label_Request_Attributes(ldp_global * g, ldp_session * s,
16480 + mpls_fec * fec, ldp_attr * r_attr, ldp_attr * s_attr)
16482 + int i;
16484 + MPLS_ASSERT(s && r_attr);
16486 + if (!(s->oper_loop_detection == LDP_LOOP_HOPCOUNT ||
16487 + s->oper_loop_detection == LDP_LOOP_HOPCOUNT_PATHVECTOR ||
16488 + r_attr->hopCountTlvExists)) { /* PRqA.1 */
16489 + return;
16492 +/* is this LSR allowed to be an LER for FEC? *//* PRqA.2 */
16493 + /* some policy gunk needs to be checked here */
16494 + /* if not goto PRqA.6 */
16496 + s_attr->hopCountTlvExists = 1; /* PRqA.3 */
16497 + s_attr->hopCountTlv.hcValue = 1;
16499 + if (s->oper_loop_detection == LDP_LOOP_NONE) { /* PRqA.4 */
16500 + return;
16503 + if (g->label_merge == MPLS_BOOL_TRUE) { /* PRqA.5 */
16504 + return;
16506 + goto Prepare_Label_Request_Attributes_13;
16508 + if (r_attr && r_attr->hopCountTlvExists) { /* PRqA.6 */
16509 + s_attr->hopCountTlvExists = 1; /* PRqA.7 */
16510 + s_attr->hopCountTlv.hcValue = (r_attr->hopCountTlv.hcValue) ?
16511 + (r_attr->hopCountTlv.hcValue + 1) : 0;
16512 + } else {
16513 + s_attr->hopCountTlvExists = 1; /* PRqA.8 */
16514 + s_attr->hopCountTlv.hcValue = 0;
16517 + if (s->oper_loop_detection == LDP_LOOP_NONE) { /* PRqA.9 */
16518 + return;
16521 + if (r_attr && r_attr->pathVecTlvExists) { /* PRqA.10 */
16522 + goto Prepare_Label_Request_Attributes_12;
16525 + if (g->label_merge == MPLS_BOOL_TRUE) { /* PRqA.11 */
16526 + return;
16528 + goto Prepare_Label_Request_Attributes_13;
16530 +Prepare_Label_Request_Attributes_12:
16531 + /* we only get to PRqA.12 if we have verified we have a r_attr */
16532 + s_attr->pathVecTlvExists = 1;
16533 + s_attr->pathVecTlv.lsrId[0] = g->lsr_identifier.u.ipv4;
16534 + for (i = 1; i < (MPLS_MAXHOPSNUMBER - 1); i++) {
16535 + if (r_attr->pathVecTlv.lsrId[i - 1]) {
16536 + s_attr->pathVecTlv.lsrId[i] = r_attr->pathVecTlv.lsrId[i - 1];
16539 + return;
16541 +Prepare_Label_Request_Attributes_13:
16542 + s_attr->pathVecTlvExists = 1;
16543 + s_attr->pathVecTlv.lsrId[0] = g->lsr_identifier.u.ipv4;
16546 +mpls_return_enum ldp_label_request_process(ldp_global * g, ldp_session * s,
16547 + ldp_adj * a, ldp_entity * e, ldp_attr * us_attr, ldp_fec * f)
16549 + ldp_session *nh_session = NULL;
16550 + ldp_nexthop *nh = NULL;
16551 + ldp_attr_list *us_list = NULL;
16552 + mpls_bool egress = MPLS_BOOL_FALSE;
16553 + mpls_bool egress_flag = MPLS_BOOL_FALSE;
16554 + ldp_attr *ds_attr = NULL;
16555 + ldp_attr *us_temp = NULL;
16557 + if (Check_Received_Attributes(g, s, us_attr, MPLS_LBLREQ_MSGTYPE) !=
16558 + MPLS_SUCCESS) { /* LRp.1 */
16559 + goto LRq_13;
16562 + if (f == NULL) {
16563 + ldp_notif_send(g, s, us_attr, LDP_NOTIF_NO_ROUTE); /* LRq.5 */
16564 + goto LRq_13;
16567 + /* just find one valid nexthop session for now */
16568 + nh = MPLS_LIST_HEAD(&f->nh_root);
16569 + while (nh) {
16570 + if (!nh_session) {
16571 + nh_session = ldp_session_for_nexthop(nh);
16573 + if (egress_flag == MPLS_BOOL_FALSE) {
16574 + egress_flag = mpls_policy_egress_check(g->user_data, &f->info, &nh->info);
16576 + nh = MPLS_LIST_NEXT(&f->nh_root, nh, _fec);
16579 + if ((!nh_session) && (egress_flag == MPLS_BOOL_TRUE)) {
16580 + egress = MPLS_BOOL_TRUE;
16582 + if (nh_session != NULL && s->index == nh_session->index) { /* LRq.3 */
16583 + ldp_notif_send(g, s, us_attr, LDP_NOTIF_LOOP_DETECTED); /* LRq.4 */
16584 + goto LRq_13;
16587 + if ((us_list = ldp_attr_find_upstream_all2(g, s, f)) != NULL) {
16588 + us_temp = MPLS_LIST_HEAD(us_list);
16589 + while (us_temp != NULL) {
16590 + if (us_temp->state == LDP_LSP_STATE_REQ_RECV && /* LRq.6 */
16591 + us_temp->msg_id == us_attr->msg_id) { /* LRq.7 */
16592 + goto LRq_13;
16594 + us_temp = MPLS_LIST_NEXT(us_list, us_temp, _fs);
16598 + us_attr->state = LDP_LSP_STATE_REQ_RECV; /* LRq.8 */
16600 + if (ldp_attr_insert_upstream2(g, s, us_attr, f) != MPLS_SUCCESS) {
16601 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_ERROR,
16602 + "Couldn't insert recv attributes in tree\n");
16603 + goto ldp_label_request_process_error;
16606 + if (nh_session) {
16607 + ds_attr = ldp_attr_find_downstream_state2(g, nh_session, f,
16608 + LDP_LSP_STATE_MAP_RECV);
16609 + } else {
16610 + ds_attr = NULL;
16613 + if (g->lsp_control_mode == LDP_CONTROL_INDEPENDENT) { /* LRq.9 */
16614 + if (ldp_label_mapping_with_xc(g, s, f, &us_attr, ds_attr) != MPLS_SUCCESS) {
16615 + goto ldp_label_request_process_error;
16618 + if (egress == MPLS_BOOL_TRUE || ds_attr) {
16619 + goto LRq_11;
16621 + } else {
16622 + if ((!(egress == MPLS_BOOL_TRUE || ds_attr)) ||
16623 + (g->label_merge == MPLS_BOOL_FALSE)) {
16624 + goto LRq_10;
16627 + if (ldp_label_mapping_with_xc(g, s, f, &us_attr, ds_attr) != MPLS_SUCCESS) {
16628 + goto ldp_label_request_process_error;
16630 + goto LRq_11;
16633 +LRq_10:
16634 + ds_attr = NULL;
16635 + if (ldp_label_request_for_xc(g, nh_session, &f->info, us_attr, &ds_attr) !=
16636 + MPLS_SUCCESS) {
16637 + goto ldp_label_request_process_error;
16640 +LRq_11:
16641 + /* the work done by LRq_11 is handled in ldp_label_mapping_with_xc() */
16642 +LRq_13:
16643 + if (ds_attr != NULL && ds_attr->in_tree == MPLS_BOOL_FALSE) {
16644 + ldp_attr_remove_complete(g, ds_attr, MPLS_BOOL_FALSE);
16646 + return MPLS_SUCCESS;
16648 +ldp_label_request_process_error:
16649 + return MPLS_FAILURE;
16651 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_label_request.h quagga-mpls/ldpd/ldp_label_request.h
16652 --- quagga/ldpd/ldp_label_request.h 1969-12-31 18:00:00.000000000 -0600
16653 +++ quagga-mpls/ldpd/ldp_label_request.h 2006-08-09 21:56:11.000000000 -0500
16654 @@ -0,0 +1,30 @@
16657 + * Copyright (C) James R. Leu 2000
16658 + * jleu@mindspring.com
16660 + * This software is covered under the LGPL, for more
16661 + * info check out http://www.gnu.org/copyleft/lgpl.html
16662 + */
16664 +#ifndef _LDP_LABEL_REQUEST_H_
16665 +#define _LDP_LABEL_REQUEST_H_
16666 +#include "ldp_struct.h"
16668 +extern void ldp_label_request_initial_callback(mpls_timer_handle timer,
16669 + void *extra, mpls_cfg_handle g);
16671 +extern mpls_return_enum ldp_label_request_send(ldp_global * g, ldp_session * s,
16672 + ldp_attr * us_attr, ldp_attr ** ds_attr);
16674 +extern mpls_return_enum ldp_label_request_process(ldp_global * g,
16675 + ldp_session * s, ldp_adj * a, ldp_entity * e, ldp_attr * r_attr,
16676 + ldp_fec * fec);
16678 +extern void Prepare_Label_Request_Attributes(ldp_global * g, ldp_session * s,
16679 + mpls_fec * fec, ldp_attr * r_attr, ldp_attr * s_attr);
16681 +extern mpls_return_enum ldp_label_request_for_xc(ldp_global * g, ldp_session * s, mpls_fec * fec, ldp_attr * us_attr, ldp_attr ** ds_attr);
16683 +extern void req2attr(mplsLdpLblReqMsg_t * req, ldp_attr * attr, uint32_t flag);
16684 +#endif
16685 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_main.c quagga-mpls/ldpd/ldp_main.c
16686 --- quagga/ldpd/ldp_main.c 1969-12-31 18:00:00.000000000 -0600
16687 +++ quagga-mpls/ldpd/ldp_main.c 2006-11-21 23:50:09.000000000 -0600
16688 @@ -0,0 +1,261 @@
16689 +#include <zebra.h>
16691 +#include "version.h"
16692 +#include "getopt.h"
16693 +#include "command.h"
16694 +#include "thread.h"
16695 +#include "filter.h"
16696 +#include "memory.h"
16697 +#include "prefix.h"
16698 +#include "log.h"
16699 +#include "privs.h"
16700 +#include "sigevent.h"
16702 +#include "ldp.h"
16703 +#include "ldp_vty.h"
16704 +#include "ldp_zebra.h"
16705 +#include "ldp_interface.h"
16707 +/* ldpd privileges */
16708 +zebra_capabilities_t _caps_p [] =
16710 + ZCAP_NET_RAW,
16711 + ZCAP_BIND,
16712 + ZCAP_NET_ADMIN,
16713 + ZCAP_SETID,
16716 +struct zebra_privs_t ldpd_privs =
16718 +#if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
16719 + .user = QUAGGA_USER,
16720 + .group = QUAGGA_GROUP,
16721 +#endif
16722 +#ifdef VTY_GROUP
16723 + .vty_group = VTY_GROUP,
16724 +#endif
16725 + .caps_p = _caps_p,
16726 + .cap_num_p = sizeof(_caps_p)/sizeof(_caps_p[0]),
16727 + .cap_num_i = 0
16730 +/* Configuration filename and directory. */
16731 +char config_default[] = SYSCONFDIR LDP_DEFAULT_CONFIG;
16733 +/* LDPd options. */
16734 +struct option longopts[] =
16736 + { "daemon", no_argument, NULL, 'd'},
16737 + { "config_file", required_argument, NULL, 'f'},
16738 + { "pid_file", required_argument, NULL, 'i'},
16739 + { "log_mode", no_argument, NULL, 'l'},
16740 + { "help", no_argument, NULL, 'h'},
16741 + { "vty_addr", required_argument, NULL, 'A'},
16742 + { "vty_port", required_argument, NULL, 'P'},
16743 + { "user", required_argument, NULL, 'u'},
16744 + { "group", required_argument, NULL, 'g'},
16745 + { "version", no_argument, NULL, 'v'},
16746 + { 0 }
16749 +/* Master of threads. */
16750 +struct thread_master *master;
16752 +/* Process ID saved for use by init system */
16753 +char *pid_file = PATH_LDPD_PID;
16755 +/* Help information display. */
16756 +static void __attribute__ ((noreturn))
16757 +usage (char *progname, int status)
16759 + if (status != 0)
16760 + fprintf (stderr, "Try `%s --help' for more information.\n", progname);
16761 + else
16762 + {
16763 + printf ("Usage : %s [OPTION...]\n\n\
16764 +Daemon which manages LDP related configuration.\n\n\
16765 +-d, --daemon Runs in daemon mode\n\
16766 +-f, --config_file Set configuration file name\n\
16767 +-i, --pid_file Set process identifier file name\n\
16768 +-A, --vty_addr Set vty's bind address\n\
16769 +-P, --vty_port Set vty's port number\n\
16770 +-u, --user User and group to run as\n\
16771 +-g, --group Group to run as\n\
16772 +-h, --help Display this help and exit\n\
16773 +-v, --version Print program version\n\
16774 +\n\
16775 +Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
16777 + exit (status);
16780 +/* SIGHUP handler. */
16781 +void
16782 +sighup (int sig)
16784 + zlog (NULL, LOG_INFO, "SIGHUP received");
16787 +/* SIGINT handler. */
16788 +void
16789 +sigint (int sig)
16791 + zlog (NULL, LOG_INFO, "Terminating on signal");
16792 + exit (0);
16795 +/* SIGUSR1 handler. */
16796 +void
16797 +sigusr1 (int sig)
16799 + zlog_rotate (NULL);
16802 +struct quagga_signal_t ldp_signals[] =
16805 + .signal = SIGHUP,
16806 + .handler = &sighup,
16807 + },
16809 + .signal = SIGUSR1,
16810 + .handler = &sigusr1,
16811 + },
16813 + .signal = SIGINT,
16814 + .handler = &sigint,
16815 + },
16817 + .signal = SIGTERM,
16818 + .handler = &sigint,
16819 + },
16823 +/* LDP main routine. */
16824 +int
16825 +main (int argc, char **argv)
16827 + char *p;
16828 + char *vty_addr = NULL;
16829 + int vty_port = LDP_VTY_PORT;
16830 + int daemon_mode = 0;
16831 + char *config_file = NULL;
16832 + char *progname;
16833 + struct thread thread;
16835 + /* Set umask before anything for security */
16836 + umask (0027);
16838 + /* preserve my name */
16839 + progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
16841 + /* Invoked by a priviledged user? -- endo. */
16842 + if (geteuid () != 0)
16844 + errno = EPERM;
16845 + perror (progname);
16846 + exit (1);
16849 + zlog_default = openzlog (progname, ZLOG_LDP,
16850 + LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
16852 + while (1)
16854 + int opt;
16856 + opt = getopt_long (argc, argv, "dlf:i:hA:P:u:g:v", longopts, 0);
16858 + if (opt == EOF)
16859 + break;
16861 + switch (opt)
16863 + case 0:
16864 + break;
16865 + case 'd':
16866 + daemon_mode = 1;
16867 + break;
16868 + case 'f':
16869 + config_file = optarg;
16870 + break;
16871 + case 'A':
16872 + vty_addr = optarg;
16873 + break;
16874 + case 'i':
16875 + pid_file = optarg;
16876 + break;
16877 + case 'P':
16878 + /* Deal with atoi() returning 0 on failure, and ldpd not
16879 + listening on ldp port... */
16880 + if (strcmp(optarg, "0") == 0)
16882 + vty_port = 0;
16883 + break;
16885 + vty_port = atoi (optarg);
16886 + vty_port = (vty_port ? vty_port : LDP_VTY_PORT);
16887 + break;
16888 + case 'u':
16889 + ldpd_privs.user = optarg;
16890 + break;
16891 + case 'g':
16892 + ldpd_privs.group = optarg;
16893 + break;
16894 + case 'v':
16895 + print_version (progname);
16896 + exit (0);
16897 + break;
16898 + case 'h':
16899 + usage (progname, 0);
16900 + break;
16901 + default:
16902 + usage (progname, 1);
16903 + break;
16907 + /* Make master thread emulator. */
16908 + master = thread_master_create ();
16910 + /* Vty related initialize. */
16911 + zprivs_init (&ldpd_privs);
16912 + signal_init (master, Q_SIGC(ldp_signals), ldp_signals);
16913 + cmd_init (1);
16914 + vty_init (master);
16915 + memory_init ();
16917 + /* LDP inits */
16918 + ldp_init ();
16919 + ldp_interface_init ();
16920 + ldp_vty_init ();
16921 + ldp_vty_show_init ();
16922 + ldp_zebra_init ();
16924 + /* Sort all installed commands. */
16925 + sort_node();
16927 + /* Configuration file read*/
16928 + vty_read_config(config_file, config_default);
16930 + /* Change to the daemon program. */
16931 + if (daemon_mode)
16932 + daemon(0, 0);
16934 + /* Process id file create. */
16935 + pid_output(pid_file);
16937 + /* Create VTY socket */
16938 + vty_serv_sock (vty_addr, vty_port, LDP_VTYSH_PATH);
16940 + /* Print banner. */
16941 + zlog_notice ("LDPd %s starting vty@%d", QUAGGA_VERSION, vty_port);
16943 + /* Fetch next active thread. */
16944 + while(thread_fetch (master, &thread))
16945 + thread_call (&thread);
16947 + /* Not reached... */
16948 + exit (0);
16950 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_mesg.c quagga-mpls/ldpd/ldp_mesg.c
16951 --- quagga/ldpd/ldp_mesg.c 1969-12-31 18:00:00.000000000 -0600
16952 +++ quagga-mpls/ldpd/ldp_mesg.c 2006-12-07 22:03:58.000000000 -0600
16953 @@ -0,0 +1,221 @@
16956 + * Copyright (C) James R. Leu 2000
16957 + * jleu@mindspring.com
16959 + * This software is covered under the LGPL, for more
16960 + * info check out http://www.gnu.org/copyleft/lgpl.html
16961 + */
16963 +#include <stdio.h>
16964 +#include <sys/socket.h>
16965 +#include "ldp_struct.h"
16966 +#include "ldp_mesg.h"
16967 +#include "ldp_buf.h"
16969 +#include "mpls_assert.h"
16970 +#include "mpls_mm_impl.h"
16971 +#include "mpls_socket_impl.h"
16972 +#include "mpls_trace_impl.h"
16974 +mpls_return_enum ldp_mesg_send_tcp(ldp_global * g, ldp_session * s,
16975 + ldp_mesg * msg)
16977 + int32_t result = 0;
16979 + MPLS_ASSERT(s);
16981 + result = ldp_encode_one_mesg(g, g->lsr_identifier.u.ipv4,
16982 + s->cfg_label_space, s->tx_buffer, msg);
16984 + if (result <= 0)
16985 + return MPLS_FAILURE;
16987 + s->mesg_tx++;
16989 + result = mpls_socket_tcp_write(g->socket_handle, s->socket,
16990 + s->tx_buffer->buffer, s->tx_buffer->size);
16992 + if (result <= 0) {
16993 + LDP_PRINT(g->user_data, "send failed(%d)\n", result);
16994 + perror("send");
16995 + return MPLS_FAILURE;
16997 + return MPLS_SUCCESS;
17000 +mpls_return_enum ldp_mesg_send_udp(ldp_global * g, ldp_entity * e,
17001 + ldp_mesg * msg)
17003 + ldp_buf *buf = NULL;
17004 + mpls_dest *dest = NULL;
17005 + int32_t result = 0;
17006 + uint16_t label_space = 0;
17008 + MPLS_ASSERT(e);
17010 + switch (e->entity_type) {
17011 + case LDP_DIRECT:
17012 + MPLS_ASSERT(e->p.iff != NULL);
17013 + if (mpls_socket_multicast_if_tx(g->socket_handle, g->hello_socket,
17014 + e->p.iff) == MPLS_FAILURE) {
17015 + LDP_PRINT(g->user_data, "ldp_mesg_send_udp: muticast tx error(%d)\n",
17016 + mpls_socket_get_errno(g->socket_handle, g->hello_socket));
17017 + return MPLS_FAILURE;
17019 + dest = &e->p.iff->dest;
17020 + buf = e->p.iff->tx_buffer;
17021 + label_space = e->p.iff->label_space;
17022 + break;
17023 + case LDP_INDIRECT:
17024 + MPLS_ASSERT(e->p.peer != NULL);
17025 + dest = &e->p.peer->dest;
17026 + buf = e->p.peer->tx_buffer;
17027 + label_space = e->p.peer->label_space;
17028 + break;
17029 + default:
17030 + MPLS_ASSERT(0);
17032 + result =
17033 + ldp_encode_one_mesg(g, g->lsr_identifier.u.ipv4, label_space, buf, msg);
17035 + if (result <= 0)
17036 + return MPLS_FAILURE;
17038 + e->mesg_tx++;
17040 + result = mpls_socket_udp_sendto(g->socket_handle, g->hello_socket,
17041 + buf->buffer, buf->size, dest);
17043 + switch (e->entity_type) {
17044 + case LDP_DIRECT:
17045 + mpls_socket_multicast_if_tx(g->socket_handle, g->hello_socket, NULL);
17046 + break;
17047 + case LDP_INDIRECT:
17048 + break;
17049 + default:
17050 + MPLS_ASSERT(0);
17053 + if (result <= 0) {
17054 + LDP_PRINT(g->user_data, "sendto failed(%d)\n", result);
17055 + perror("sendto");
17056 + return MPLS_FAILURE;
17058 + return MPLS_SUCCESS;
17061 +ldp_mesg *ldp_mesg_create()
17063 + ldp_mesg *msg = (ldp_mesg *) mpls_malloc(sizeof(ldp_mesg));
17065 + if (!msg) {
17066 + return NULL;
17068 + return msg;
17071 +void ldp_mesg_prepare(ldp_mesg * msg, uint16_t type, uint32_t id)
17073 + memset(msg, 0, sizeof(ldp_mesg));
17075 + msg->u.generic.flags.flags.msgType = type;
17076 + msg->u.generic.msgId = id;
17077 + msg->u.generic.msgLength = MPLS_MSGIDFIXLEN;
17080 +void ldp_mesg_delete(ldp_mesg * msg)
17082 + MPLS_ASSERT(msg);
17083 + mpls_free(msg);
17086 +void ldp_mesg_hdr_get_lsraddr(ldp_mesg * msg, mpls_inet_addr * lsraddr)
17088 + MPLS_ASSERT(msg && lsraddr);
17090 + lsraddr->type = MPLS_FAMILY_IPV4;
17091 + lsraddr->u.ipv4 = msg->header.lsrAddress;
17094 +void ldp_mesg_hdr_get_labelspace(ldp_mesg * msg, int *labelspace)
17096 + MPLS_ASSERT(msg && labelspace);
17097 + *labelspace = msg->header.labelSpace;
17100 +uint16_t ldp_mesg_get_type(ldp_mesg * msg)
17102 + MPLS_ASSERT(msg);
17103 + return msg->u.generic.flags.flags.msgType;
17106 +mpls_return_enum ldp_mesg_hello_get_traddr(ldp_mesg * msg,
17107 + mpls_inet_addr * traddr)
17109 + MPLS_MSGPTR(Hello);
17110 + MPLS_ASSERT(msg && traddr);
17112 + MPLS_MSGPARAM(Hello) = &msg->u.hello;
17113 + if (!MPLS_MSGPARAM(Hello)->trAdrTlvExists)
17114 + return MPLS_FAILURE;
17116 + traddr->type = MPLS_FAMILY_IPV4;
17117 + traddr->u.ipv4 = MPLS_MSGPARAM(Hello)->trAdr.address;
17119 + return MPLS_SUCCESS;
17122 +mpls_return_enum ldp_mesg_hello_get_hellotime(ldp_mesg * msg, int *hellotime)
17124 + MPLS_MSGPTR(Hello);
17125 + MPLS_ASSERT(msg && hellotime);
17127 + MPLS_MSGPARAM(Hello) = &msg->u.hello;
17128 + if (!MPLS_MSGPARAM(Hello)->chpTlvExists) {
17129 + LDP_PRINT(NULL, "No chp!");
17130 + return MPLS_FAILURE;
17133 + *hellotime = MPLS_MSGPARAM(Hello)->chp.holdTime;
17135 + return MPLS_SUCCESS;
17138 +mpls_return_enum ldp_mesg_hello_get_csn(ldp_mesg * msg, uint32_t * csn)
17140 + MPLS_MSGPTR(Hello);
17141 + MPLS_ASSERT(msg && csn);
17143 + MPLS_MSGPARAM(Hello) = &msg->u.hello;
17144 + if (!MPLS_MSGPARAM(Hello)->csnTlvExists)
17145 + return MPLS_FAILURE;
17147 + *csn = MPLS_MSGPARAM(Hello)->csn.seqNumber;
17149 + return MPLS_SUCCESS;
17152 +mpls_return_enum ldp_mesg_hello_get_request(ldp_mesg * msg, int *req)
17154 + MPLS_MSGPTR(Hello);
17155 + MPLS_ASSERT(msg && req);
17157 + MPLS_MSGPARAM(Hello) = &msg->u.hello;
17159 + *req = MPLS_MSGPARAM(Hello)->chp.flags.flags.request;
17161 + return MPLS_SUCCESS;
17164 +mpls_return_enum ldp_mesg_hello_get_targeted(ldp_mesg * msg, int *tar)
17166 + MPLS_MSGPTR(Hello);
17167 + MPLS_ASSERT(msg && tar);
17169 + MPLS_MSGPARAM(Hello) = &msg->u.hello;
17171 + *tar = MPLS_MSGPARAM(Hello)->chp.flags.flags.target;
17173 + return MPLS_SUCCESS;
17175 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_mesg.h quagga-mpls/ldpd/ldp_mesg.h
17176 --- quagga/ldpd/ldp_mesg.h 1969-12-31 18:00:00.000000000 -0600
17177 +++ quagga-mpls/ldpd/ldp_mesg.h 2006-08-09 21:56:10.000000000 -0500
17178 @@ -0,0 +1,36 @@
17181 + * Copyright (C) James R. Leu 2001
17182 + * jleu@mindspring.com
17184 + * This software is covered under the LGPL, for more
17185 + * info check out http://www.gnu.org/copyleft/lgpl.html
17186 + */
17188 +#ifndef _LDP_MESG_H_
17189 +#define _LDP_MESG_H_
17191 +#include "ldp_struct.h"
17193 +extern ldp_mesg *ldp_mesg_create();
17194 +extern void ldp_mesg_prepare(ldp_mesg * msg, uint16_t type, uint32_t id);
17195 +extern void ldp_mesg_delete(ldp_mesg * msg);
17196 +extern uint16_t ldp_mesg_get_type(ldp_mesg * mesg);
17197 +extern void ldp_mesg_hdr_get_lsraddr(ldp_mesg * mesg, mpls_inet_addr * lsraddr);
17198 +extern void ldp_mesg_hdr_get_labelspace(ldp_mesg * mesg, int *labelspace);
17200 +extern mpls_return_enum ldp_mesg_hello_get_traddr(ldp_mesg * mesg,
17201 + mpls_inet_addr * traddr);
17202 +extern mpls_return_enum ldp_mesg_hello_get_hellotime(ldp_mesg * mesg,
17204 + int *hellotime);
17205 +extern mpls_return_enum ldp_mesg_hello_get_csn(ldp_mesg * mesg, uint32_t * csn);
17206 +extern mpls_return_enum ldp_mesg_hello_get_targeted(ldp_mesg * mesg, int *tar);
17207 +extern mpls_return_enum ldp_mesg_hello_get_request(ldp_mesg * mesg, int *req);
17209 +extern mpls_return_enum ldp_mesg_send_tcp(ldp_global * g, ldp_session * s,
17210 + ldp_mesg * mesg);
17211 +extern mpls_return_enum ldp_mesg_send_udp(ldp_global * g, ldp_entity * s,
17212 + ldp_mesg * mesg);
17214 +#endif
17215 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_nexthop.c quagga-mpls/ldpd/ldp_nexthop.c
17216 --- quagga/ldpd/ldp_nexthop.c 1969-12-31 18:00:00.000000000 -0600
17217 +++ quagga-mpls/ldpd/ldp_nexthop.c 2006-12-07 22:03:34.000000000 -0600
17218 @@ -0,0 +1,217 @@
17221 + * Copyright (C) James R. Leu 2003
17222 + * jleu@mindspring.com
17224 + * This software is covered under the LGPL, for more
17225 + * info check out http://www.gnu.org/copyleft/lgpl.html
17226 + */
17228 +#include "ldp_struct.h"
17229 +#include "ldp_fec.h"
17230 +#include "ldp_if.h"
17231 +#include "ldp_addr.h"
17232 +#include "ldp_session.h"
17233 +#include "ldp_outlabel.h"
17234 +#include "ldp_global.h"
17235 +#include "mpls_assert.h"
17236 +#include "mpls_compare.h"
17237 +#include "mpls_mm_impl.h"
17238 +#include "mpls_tree_impl.h"
17239 +#include "mpls_policy_impl.h"
17240 +#include "mpls_trace_impl.h"
17242 +#if MPLS_USE_LSR
17243 +#include "lsr_cfg.h"
17244 +#else
17245 +#include "mpls_mpls_impl.h"
17246 +#endif
17248 +static uint32_t _ldp_nexthop_next_index = 1;
17249 +static uint32_t _ldp_nexthop_get_next_index();
17251 +void mpls_nexthop2ldp_nexthop(mpls_nexthop *mnh, ldp_nexthop *lnh)
17253 + memcpy(&lnh->info, mnh, sizeof(mpls_nexthop));
17256 +ldp_nexthop *ldp_nexthop_for_fec_session(ldp_fec *fec, ldp_session *s)
17258 + ldp_nexthop *nh = MPLS_LIST_HEAD(&fec->nh_root);
17259 + ldp_session *sp;
17261 + LDP_ENTER(g->user_data, "ldp_nexthop_for_fec_session");
17263 + while (nh) {
17264 + sp = ldp_session_for_nexthop(nh);
17265 + if (sp && (sp->index == s->index)) {
17266 + LDP_EXIT(g->user_data, "ldp_nexthop_for_fec_session: %p", nh);
17267 + return nh;
17269 + nh = MPLS_LIST_NEXT(&fec->nh_root, nh, _fec);
17271 + LDP_EXIT(g->user_data, "ldp_nexthop_for_fec_session: NULL");
17272 + return NULL;
17275 +void ldp_nexthop_delete(ldp_global *g, ldp_nexthop *nh)
17277 + LDP_PRINT(g->user_data, "nexthop delete: %p", nh);
17278 + MPLS_REFCNT_ASSERT(nh, 0);
17280 + if (nh->addr) {
17281 + ldp_addr_del_nexthop(g, nh->addr, nh);
17283 + if (nh->iff) {
17284 + ldp_if_del_nexthop(g, nh->iff, nh);
17286 + if (nh->outlabel) {
17287 + ldp_outlabel_del_nexthop(g, nh->outlabel, nh);
17290 + _ldp_global_del_nexthop(g, nh);
17291 + mpls_free(nh);
17294 +ldp_nexthop *ldp_nexthop_create(ldp_global *g, mpls_nexthop *n)
17296 + ldp_nexthop *nh = (ldp_nexthop *) mpls_malloc(sizeof(ldp_nexthop));
17298 + if (nh != NULL) {
17299 + memset(nh, 0, sizeof(ldp_nexthop));
17300 + MPLS_REFCNT_INIT(nh, 0);
17301 + MPLS_LIST_INIT(&nh->outlabel_root, ldp_outlabel);
17302 + MPLS_LIST_ELEM_INIT(nh, _global);
17303 + MPLS_LIST_ELEM_INIT(nh, _fec);
17304 + MPLS_LIST_ELEM_INIT(nh, _addr);
17305 + MPLS_LIST_ELEM_INIT(nh, _if);
17306 + MPLS_LIST_ELEM_INIT(nh, _outlabel);
17307 + nh->index = _ldp_nexthop_get_next_index();
17308 + mpls_nexthop2ldp_nexthop(n, nh);
17310 + if (nh->info.type & MPLS_NH_IP) {
17311 + ldp_addr *addr = NULL;
17312 + if (!(addr = ldp_addr_find(g, &nh->info.ip))) {
17313 + if (!(addr = ldp_addr_insert(g, &nh->info.ip))) {
17314 + goto ldp_nexthop_create_error;
17317 + ldp_addr_add_nexthop(addr, nh);
17320 + if (nh->info.type & MPLS_NH_IF) {
17321 + ldp_if *iff = NULL;
17322 + if ((iff = ldp_global_find_if_handle(g, nh->info.if_handle))) {
17323 + ldp_if_add_nexthop(iff, nh);
17324 + } else {
17325 + goto ldp_nexthop_create_error;
17329 + if (nh->info.type & MPLS_NH_OUTSEGMENT) {
17330 + ldp_outlabel *out = NULL;
17331 + MPLS_ASSERT((out = ldp_global_find_outlabel_handle(g,
17332 + nh->info.outsegment_handle)));
17333 + ldp_outlabel_add_nexthop(out, nh);
17336 + _ldp_global_add_nexthop(g, nh);
17338 + return nh;
17340 +ldp_nexthop_create_error:
17341 + ldp_nexthop_delete(g, nh);
17342 + return NULL;
17345 +void ldp_nexthop_add_if(ldp_nexthop * nh, ldp_if * i)
17347 + MPLS_ASSERT(nh && i);
17348 + MPLS_REFCNT_HOLD(i);
17349 + nh->info.if_handle = i->handle;
17350 + nh->iff = i;
17353 +void ldp_nexthop_del_if(ldp_global *g, ldp_nexthop * nh)
17355 + MPLS_ASSERT(nh);
17356 + MPLS_REFCNT_RELEASE2(g, nh->iff, ldp_if_delete);
17357 + nh->iff = NULL;
17360 +void ldp_nexthop_add_addr(ldp_nexthop * nh, ldp_addr * a)
17362 + MPLS_ASSERT(nh && a);
17363 + MPLS_REFCNT_HOLD(a);
17364 + nh->addr = a;
17367 +void ldp_nexthop_del_addr(ldp_global *g, ldp_nexthop * nh)
17369 + MPLS_ASSERT(nh);
17370 + MPLS_REFCNT_RELEASE2(g, nh->addr, ldp_addr_delete);
17371 + nh->addr = NULL;
17374 +/* this is for a nexthops outlabel used to describe hierarchy */
17375 +void ldp_nexthop_add_outlabel(ldp_nexthop * nh, ldp_outlabel * o)
17377 + MPLS_ASSERT(nh && o);
17378 + MPLS_REFCNT_HOLD(o);
17379 + nh->outlabel = o;
17382 +/* this is for a nexthops outlabel used to describe hierarchy */
17383 +void ldp_nexthop_del_outlabel(ldp_global * g,ldp_nexthop * nh)
17385 + MPLS_ASSERT(nh);
17386 + MPLS_REFCNT_RELEASE2(g, nh->outlabel, ldp_outlabel_delete);
17387 + nh->outlabel = NULL;
17391 + * just like addrs with respect to NHs, NHs do not need to hold a ref to
17392 + * outlabels (upper).
17393 + */
17395 +/* this is for the outlabels nexthops, not the nexthop's outlabel
17396 + * used to describe hierarchy */
17397 +void ldp_nexthop_add_outlabel2(ldp_nexthop * n, ldp_outlabel * o)
17399 + MPLS_ASSERT(n && o);
17400 + MPLS_LIST_ADD_HEAD(&n->outlabel_root, o, _nexthop, ldp_outlabel);
17401 + memcpy(&o->info.nexthop, &n->info, sizeof(mpls_nexthop));
17404 +/* this is for the outlabels nexthops, not the nexthop's outlabel
17405 + * used to describe hierarchy */
17406 +void ldp_nexthop_del_outlabel2(ldp_global *g, ldp_nexthop * n, ldp_outlabel * o)
17408 + MPLS_ASSERT(n && o);
17409 + MPLS_LIST_REMOVE(&n->outlabel_root, o, _nexthop);
17412 +void ldp_nexthop_add_fec(ldp_nexthop *nh, ldp_fec *f)
17414 + MPLS_ASSERT(nh && f);
17415 + MPLS_REFCNT_HOLD(f);
17416 + nh->fec = f;
17419 +void ldp_nexthop_del_fec(ldp_global *g, ldp_nexthop * nh)
17421 + MPLS_ASSERT(nh);
17422 + MPLS_REFCNT_RELEASE2(g, nh->fec, ldp_fec_delete);
17423 + nh->fec = NULL;
17426 +static uint32_t _ldp_nexthop_get_next_index()
17428 + uint32_t retval = _ldp_nexthop_next_index;
17430 + _ldp_nexthop_next_index++;
17431 + if (retval > _ldp_nexthop_next_index) {
17432 + _ldp_nexthop_next_index = 1;
17434 + return retval;
17436 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_nexthop.h quagga-mpls/ldpd/ldp_nexthop.h
17437 --- quagga/ldpd/ldp_nexthop.h 1969-12-31 18:00:00.000000000 -0600
17438 +++ quagga-mpls/ldpd/ldp_nexthop.h 2006-08-24 22:42:08.000000000 -0500
17439 @@ -0,0 +1,29 @@
17442 + * Copyright (C) James R. Leu 2003
17443 + * jleu@mindspring.com
17445 + * This software is covered under the LGPL, for more
17446 + * info check out http://www.gnu.org/copyleft/lgpl.html
17447 + */
17449 +#ifndef _LDP_NEXTHOP_H_
17450 +#define _LDP_NEXTHOP_H_
17452 +extern ldp_nexthop *ldp_nexthop_create(ldp_global *g, mpls_nexthop *n);
17453 +extern ldp_nexthop *ldp_nexthop_for_fec_session(ldp_fec *fec, ldp_session *s);
17454 +extern void ldp_nexthop_delete(ldp_global *g, ldp_nexthop *nh);
17455 +extern void ldp_nexthop_add_if(ldp_nexthop * nh, ldp_if * i);
17456 +extern void ldp_nexthop_del_if(ldp_global *g, ldp_nexthop * nh);
17457 +extern void ldp_nexthop_add_addr(ldp_nexthop * nh, ldp_addr * a);
17458 +extern void ldp_nexthop_del_addr(ldp_global *g, ldp_nexthop * nh);
17459 +extern void ldp_nexthop_add_outlabel(ldp_nexthop * nh, ldp_outlabel * o);
17460 +extern void ldp_nexthop_del_outlabel(ldp_global *g, ldp_nexthop * nh);
17461 +extern void ldp_nexthop_add_outlabel2(ldp_nexthop * nh, ldp_outlabel * o);
17462 +extern void ldp_nexthop_del_outlabel2(ldp_global *g, ldp_nexthop * nh, ldp_outlabel * o);
17463 +extern void ldp_nexthop_add_fec(ldp_nexthop * nh, ldp_fec * f);
17464 +extern void ldp_nexthop_del_fec(ldp_global * g, ldp_nexthop * nh);
17465 +extern void mpls_nexthop2ldp_nexthop(mpls_nexthop *mnh, ldp_nexthop *lnh);
17468 +#endif
17469 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_nortel.c quagga-mpls/ldpd/ldp_nortel.c
17470 --- quagga/ldpd/ldp_nortel.c 1969-12-31 18:00:00.000000000 -0600
17471 +++ quagga-mpls/ldpd/ldp_nortel.c 2006-08-09 21:56:17.000000000 -0500
17472 @@ -0,0 +1,5769 @@
17474 +/******************************************************************************
17475 +* Nortel Networks Software License *
17476 +* *
17477 +* READ THE TERMS OF THIS LICENSE CAREFULLY. BY USING, MODIFYING, OR *
17478 +* DISTRIBUTING THIS SOFTWARE AND ANY ACCOMPANYING DOCUMENTATION (COLLECTIVELY,*
17479 +* "SOFTWARE") YOU ARE AGREEING TO ALL OF THE TERMS OF THIS LICENSE. *
17480 +* *
17481 +* 1. Nortel Telecom Limited, on behalf of itself and its subsidiaries *
17482 +* (collectively "Nortel Networks") grants to you a non-exclusive, perpetual, *
17483 +* world-wide right to use, copy, modify, and distribute the Software at no *
17484 +* charge. *
17485 +* *
17486 +* 2. You may sublicense recipients of redistributed Software to use, *
17487 +* copy, modify, and distribute the Software on substantially the same terms as*
17488 +* this License. You may not impose any further restrictions on the *
17489 +* recipient's exercise of the rights in the Software granted under this *
17490 +* License. Software distributed to other parties must be accompanied by a *
17491 +* License containing a grant, disclaimer and limitation of liability *
17492 +* substantially in the form of 3, 4, and 5 below provided that references to *
17493 +* "Nortel Networks" may be changed to "Supplier". *
17494 +* *
17495 +* 3. Nortel Networks reserves the right to modify and release new *
17496 +* versions of the Software from time to time which may include modifications *
17497 +* made by third parties like you. Accordingly, you agree that you shall *
17498 +* automatically grant a license to Nortel Networks to include, at its option, *
17499 +* in any new version of the Software any modifications to the Software made by*
17500 +* you and made available directly or indirectly to Nortel Networks. Nortel *
17501 +* Networks shall have the right to use, copy, modify, and distribute any such *
17502 +* modified Software on substantially the same terms as this License. *
17503 +* *
17504 +* 4. THE SOFTWARE IS PROVIDED ON AN "AS IS" BASIS. NORTEL NETWORKS AND *
17505 +* ITS AGENTS AND SUPPLIERS DISCLAIM ALL REPRESENTATIONS, WARRANTIES AND *
17506 +* CONDITIONS RELATING TO THE SOFTWARE, INCLUDING, BUT NOT LIMITED TO, IMPLIED *
17507 +* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
17508 +* NON-INFRINGEMENT OF THIRD-PARTY INTELLECTUAL PROPERTY RIGHTS. NORTEL *
17509 +* NETWORKS AND ITS AGENTS AND SUPPLIERS DO NOT WARRANT, GUARANTEE, OR MAKE ANY*
17510 +* REPRESENTATIONS REGARDING THE USE, OR THE RESULTS OF THE USE, OF THE *
17511 +* SOFTWARE IN TERMS OR CORRECTNESS, ACCURACY, RELIABILITY, CURRENTNESS, OR *
17512 +* OTHERWISE. *
17513 +* *
17514 +* 5. NEITHER NORTEL NETWORKS NOR ANY OF ITS AGENTS OR SUPPLIERS SHALL BE *
17515 +* LIABLE FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR EXEMPLARY *
17516 +* DAMAGES, OR ECONOMIC LOSSES (INCLUDING DAMAGES FOR LOSS OF BUSINESS PROFITS,*
17517 +* BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION AND THE LIKE), ARISING *
17518 +* FROM THE SOFTWARE OR THIS LICENSE AGREEMENT, EVEN IF NORTEL NETWORKS OR SUCH*
17519 +* AGENT OR SUPPLIER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES OR *
17520 +* LOSSES, AND WHETHER ANY SUCH DAMAGE OR LOSS ARISES OUT OF CONTRACT, TORT, OR*
17521 +* OTHERWISE. *
17522 +* *
17523 +* 6. This License shall be governed by the laws of the Province of *
17524 +* Ontario, Canada. *
17525 +*******************************************************************************/
17527 +/******************************************************************************
17528 + * This file contains the C implementation for encode/decode functions *
17529 + * for the following types of messages: notification, hello, initialization, *
17530 + * keepAlive, address, address Withdraw, label Mapping, label Request, label *
17531 + * Withdraw and label Release. There are also encode/decode methods for all *
17532 + * tlv types required by the previously enumerated messages. *
17533 + * Please remember that the pdu will always contain the header followed by 1 *
17534 + * or more LDP messages. The file contains functions to encode/decode the LDP *
17535 + * header as well. *
17536 + * All the messages, header message and the tlvs are in conformity with the *
17537 + * draft-ietf-mpls-ldp-04 (May 1999) and with draft-ietf-mpls-cr-ldp-01 *
17538 + * (Jan 1999). *
17539 + * *
17540 + * Please note that the U bit in the message and the F bit in the tlv are *
17541 + * ignored in this version of the code. *
17542 + * *
17543 + * Please note that the traffic parameters for traffic TLV have to be IEEE *
17544 + * single precision floating point numbers. *
17545 + * *
17546 + * Please note that there might be a small chance for bit field manipulation *
17547 + * portability inconsistency. If such problems occure, the code requires *
17548 + * changes for a suitable bit-field manipulation. The code for encoding and *
17549 + * decoding makes the assumption that the compiler packs the bit fields in a *
17550 + * structure into adjacent bits of the same unit. *
17551 + * *
17552 + * The usage of the encode/decode functions is described below. *
17553 + * *
17554 + * The encode functions take as arguments: a pointer to the structure which *
17555 + * implements msg/tlv, a buffer (where the encoding is done) and the buffer *
17556 + * length. *
17557 + * If the encode is successfull, the function returns the total encoded *
17558 + * length. *
17559 + * If the encode fails, the function returns an error code. *
17560 + * The encode functions for messages and message headers do not modify the *
17561 + * content of the struct which is to be encoded. All the other encode *
17562 + * functions will change the content of the structure. The pointer which *
17563 + * points to the beginning of the buffer is not changed. *
17564 + * *
17565 + * The decode functions take as arguments: a pointer to the structure which *
17566 + * is going to be populated after decoding, a pointer to a buffer and the *
17567 + * buffer length. *
17568 + * If the decode is successful, the function returns the total decoded length *
17569 + * If the decode fails, the function returns an error code. The decode *
17570 + * functions do not modify the pointer to the buffer which contains the data *
17571 + * to be decoded. *
17572 + * *
17573 + * Example on how to use the encode/decode functions for a keepAlive message: *
17574 + * *
17575 + * Encode the keep alive message: *
17576 + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ *
17577 + * u_char buffer[500]; *
17578 + * int returnCode; *
17579 + * struct mplsLdpKeepAlMsg_s keepAliveMsg; *
17580 + * keepAliveMsg.baseMsg.msgType = MPLS_KEEPAL_MSGTYPE; *
17581 + * keepAliveMsg.baseMsg.msgLength = MPLS_MSGIDFIXLEN; *
17582 + * keepAliveMsg.baseMsg.msgId = 123; *
17583 + * memset(buffer, 0, 500); *
17584 + * returnCode = Mpls_encodeLdpKeepAliveMsg(&keepAliveMsg, *
17585 + * buffer, *
17586 + * 500); *
17587 + * if (returnCode < 0) *
17588 + * check the error code *
17589 + * else *
17590 + * write(fd, buffer, returnCode); *
17591 + * *
17592 + * *
17593 + * Decode the keep alive meesage: *
17594 + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ *
17595 + * u_char buffer[500]; *
17596 + * int returnCode; *
17597 + * struct mplsLdpKeepAlMsg_s keepAliveMsg; *
17598 + * read(fd, buffer, length); *
17599 + * returnCode = Mpls_decodeLdpKeepAliveMsg(&keepAliveMsg, *
17600 + * buffer, *
17601 + * 500); *
17602 + * if (returnCode < 0) *
17603 + * check the error code *
17604 + * else *
17605 + * { *
17606 + * printKeepAliveMsg(&keepAliveMsg); *
17607 + * } *
17608 + * *
17609 + * An example on how to use the decode functions for the header and the *
17610 + * messages can be found in the main function. *
17611 + * *
17612 + * The code was tested for big endian and little endian for sparc5, linux *
17613 + * and i960. *
17614 + * *
17615 + * In order to compile for little endian, the LITTLE_ENDIAN_BYTE_ORDER should *
17616 + * be defined. *
17617 + * *
17618 + * At the end of this file there is an examples of a hex buffers and its *
17619 + * corresponding values. *
17620 + * *
17621 + * *
17622 + * Version History *
17623 + * Version Date Authors Description *
17624 + * =========== ======== ========= ====================== *
17625 + * mpls_encdec_01.c 99/03/15 Antonela Paraschiv draft-ietf-mpls-ldp-03 and *
17626 + * draft-ietf-mpls-cr-ldp-01 *
17627 + * *
17628 + * mpls_encdec_02.c 99/05/19 Antonela Paraschiv draft-ietf-mpls-ldp-04 and *
17629 + * draft-ietf-mpls-cr-ldp-01 *
17630 + * *
17631 + ******************************************************************************/
17633 +#ifdef VXWORKS
17634 +#include <in.h> /* htons, htonl, ntohs, ntohl */
17635 +#include <types.h> /* u_int, u_char, u_short, float etc. */
17636 +#else
17637 +#include <netinet/in.h> /* htons, htonl, ntohs, ntohl */
17638 +#include <sys/types.h> /* u_int, u_char, u_short, float etc. */
17639 +#endif /* VXWORKS */
17641 +#include "ldp_struct.h"
17642 +#include "mpls_trace_impl.h"
17643 +#include "ldp_nortel.h"
17645 +int global_ldp_pdu_debug = 0;
17648 + * Encode-decode for Ldp Msg Header
17649 + */
17651 +/*
17652 + * Encode:
17653 + */
17654 +int Mpls_encodeLdpMsgHeader
17655 + (mplsLdpHeader_t * header, u_char * buff, int bufSize) {
17656 + mplsLdpHeader_t headerCopy;
17658 + if (MPLS_LDP_HDRSIZE > bufSize) {
17659 + /* not enough room for header */
17660 + return MPLS_ENC_BUFFTOOSMALL;
17663 + headerCopy = *header;
17664 + headerCopy.protocolVersion = htons(headerCopy.protocolVersion);
17665 + headerCopy.pduLength = htons(headerCopy.pduLength);
17666 + headerCopy.lsrAddress = htonl(headerCopy.lsrAddress);
17667 + headerCopy.labelSpace = htons(headerCopy.labelSpace);
17669 + MEM_COPY(buff, (u_char *) & headerCopy, MPLS_LDP_HDRSIZE);
17671 + return MPLS_LDP_HDRSIZE;
17673 +} /* End : Mpls_encodeLdpMsgHeader */
17675 +/*
17676 + * Decode:
17677 + */
17678 +int Mpls_decodeLdpMsgHeader
17679 + (mplsLdpHeader_t * header, u_char * buff, int bufSize) {
17680 + if (MPLS_LDP_HDRSIZE > bufSize) {
17681 + return MPLS_DEC_BUFFTOOSMALL;
17684 + MEM_COPY((u_char *) header, buff, MPLS_LDP_HDRSIZE);
17686 + header->protocolVersion = ntohs(header->protocolVersion);
17687 + header->pduLength = ntohs(header->pduLength);
17688 + header->lsrAddress = ntohl(header->lsrAddress);
17689 + header->labelSpace = ntohs(header->labelSpace);
17691 + /* check if the length is over the max length */
17692 + if (header->pduLength > MPLS_PDUMAXLEN) {
17693 + return MPLS_PDU_LENGTH_ERROR;
17696 + return MPLS_LDP_HDRSIZE;
17698 +} /* End: Mpls_decodeLdpMsgHeader */
17701 + * Encode-decode for Ldp Base Message
17702 + */
17704 +/*
17705 + * Encode:
17706 + */
17707 +int Mpls_encodeLdpBaseMsg(mplsLdpMsg_t * ldpMsg, u_char * buff, int bufSize)
17709 + if (MPLS_MSGIDFIXLEN + MPLS_TLVFIXLEN > bufSize) {
17710 + /* not enough room for header */
17711 + return MPLS_ENC_BUFFTOOSMALL;
17714 + ldpMsg->flags.mark = htons(ldpMsg->flags.mark);
17715 + ldpMsg->msgLength = htons(ldpMsg->msgLength);
17716 + ldpMsg->msgId = htonl(ldpMsg->msgId);
17718 + MEM_COPY(buff, (u_char *) ldpMsg, MPLS_MSGIDFIXLEN + MPLS_TLVFIXLEN);
17720 + return (MPLS_MSGIDFIXLEN + MPLS_TLVFIXLEN);
17722 +} /* End : Mpls_encodeLdpBaseMsg */
17724 +/*
17725 + * Decode:
17726 + */
17727 +int Mpls_decodeLdpBaseMsg(mplsLdpMsg_t * ldpMsg, u_char * buff, int bufSize)
17729 + if (MPLS_MSGIDFIXLEN + MPLS_TLVFIXLEN > bufSize) {
17730 + return MPLS_DEC_BUFFTOOSMALL;
17733 + MEM_COPY((u_char *) ldpMsg, buff, MPLS_MSGIDFIXLEN + MPLS_TLVFIXLEN);
17735 + ldpMsg->flags.mark = ntohs(ldpMsg->flags.mark);
17736 + ldpMsg->msgLength = ntohs(ldpMsg->msgLength);
17737 + ldpMsg->msgId = ntohl(ldpMsg->msgId);
17739 + return MPLS_MSGIDFIXLEN + MPLS_TLVFIXLEN;
17741 +} /* End: Mpls_decodeLdpBaseMsg */
17744 + * Encode-decode for ATM Label Range Component
17745 + */
17747 +/*
17748 + * encode:
17749 + */
17750 +int Mpls_encodeLdpAtmLblRng
17751 + (mplsLdpAtmLblRng_t * atmLbl, u_char * buff, int bufSize) {
17752 + if (MPLS_ATMLRGFIXLEN > bufSize) {
17753 + /* not enough room for label */
17754 + return MPLS_ENC_BUFFTOOSMALL;
17757 + atmLbl->flags.flags.res1 = 0;
17758 + atmLbl->flags.flags.res2 = 0;
17759 + atmLbl->flags.mark[0] = htonl(atmLbl->flags.mark[0]);
17760 + atmLbl->flags.mark[1] = htonl(atmLbl->flags.mark[1]);
17762 + MEM_COPY(buff, (u_char *) atmLbl, MPLS_ATMLRGFIXLEN);
17764 + return MPLS_ATMLRGFIXLEN;
17766 +} /* End Mpls_encodeLdpAtmLblRng */
17768 +/*
17769 + * decode:
17770 + */
17771 +int Mpls_decodeLdpAtmLblRng
17772 + (mplsLdpAtmLblRng_t * atmLbl, u_char * buff, int bufSize) {
17773 + if (MPLS_ATMLRGFIXLEN > bufSize) {
17774 + PRINT_ERR("failed decoding the Atm Lbl Rng\n");
17775 + return MPLS_DEC_BUFFTOOSMALL;
17778 + MEM_COPY((u_char *) atmLbl, buff, MPLS_ATMLRGFIXLEN);
17780 + atmLbl->flags.mark[0] = ntohl(atmLbl->flags.mark[0]);
17781 + atmLbl->flags.mark[1] = ntohl(atmLbl->flags.mark[1]);
17783 + return MPLS_ATMLRGFIXLEN;
17785 +} /* End Mpls_decodeLdpAtmLblRng */
17788 + * Encode-decode for ATM Session Parameters
17789 + */
17791 +/*
17792 + * encode:
17793 + */
17794 +int Mpls_encodeLdpAsp(mplsLdpAspTlv_t * atmAsp, u_char * buff, int bufSize)
17796 + int encodedSize = 0;
17797 + u_short totalSize = 0;
17798 + u_char *tempBuf = buff; /* no change for the buff ptr */
17799 + u_int i, numLblRng;
17801 + /* get the size of the atmAsp to be encoded and check it against
17802 + the buffer size */
17804 + if (MPLS_TLVFIXLEN + (int)(atmAsp->baseTlv.length) > bufSize) {
17805 + /* not enough room */
17806 + return MPLS_ENC_BUFFTOOSMALL;
17809 + /*
17810 + * encode for tlv
17811 + */
17812 + encodedSize = Mpls_encodeLdpTlv(&(atmAsp->baseTlv), tempBuf, bufSize);
17813 + if (encodedSize < 0) {
17814 + return MPLS_ENC_TLVERROR;
17816 + tempBuf += encodedSize;
17817 + totalSize += encodedSize;
17819 + /*
17820 + * encode for M + N + D + res
17821 + */
17822 + numLblRng = atmAsp->flags.flags.numLblRng;
17823 + atmAsp->flags.flags.res = 0;
17824 + atmAsp->flags.mark = htonl(atmAsp->flags.mark);
17826 + MEM_COPY(tempBuf, (u_char *) & (atmAsp->flags.mark), MPLS_ASPFIXLEN);
17827 + tempBuf += MPLS_ASPFIXLEN;
17828 + totalSize += MPLS_ASPFIXLEN;
17830 + /*
17831 + * encode for ATM labels
17832 + */
17833 + for (i = 0; i < numLblRng; i++) {
17834 + encodedSize = Mpls_encodeLdpAtmLblRng(&(atmAsp->lblRngList[i]),
17835 + tempBuf, bufSize - totalSize);
17836 + if (encodedSize < 0) {
17837 + return MPLS_ENC_ATMLBLERROR;
17839 + tempBuf += encodedSize;
17840 + totalSize += encodedSize;
17843 + return totalSize;
17845 +} /* End Mpls_encodeLdpAsp */
17847 +/*
17848 + * decode:
17849 + */
17850 +int Mpls_decodeLdpAsp(mplsLdpAspTlv_t * atmAsp, u_char * buff, int bufSize)
17852 + int decodedSize = 0;
17853 + u_short totalSize = 0;
17854 + u_char *tempBuf = buff; /* no change for the buff ptr */
17855 + u_int i;
17857 + if (MPLS_ASPFIXLEN > bufSize) {
17858 + /* the buffer does not contain even the required field */
17859 + PRINT_ERR("failed in decoding LdpAsp\n");
17860 + return MPLS_DEC_BUFFTOOSMALL;
17863 + /*
17864 + * decode for M + N + D + res
17865 + */
17866 + MEM_COPY((u_char *) & (atmAsp->flags.mark), tempBuf, MPLS_ASPFIXLEN);
17867 + tempBuf += MPLS_ASPFIXLEN;
17868 + totalSize += MPLS_ASPFIXLEN;
17870 + atmAsp->flags.mark = ntohl(atmAsp->flags.mark);
17872 + /*
17873 + * decode for ATM labels
17874 + */
17875 + for (i = 0; i < atmAsp->flags.flags.numLblRng; i++) {
17876 + decodedSize = Mpls_decodeLdpAtmLblRng(&(atmAsp->lblRngList[i]),
17877 + tempBuf, bufSize - totalSize);
17878 + if (decodedSize < 0) {
17879 + PRINT_ERR("failed in decoding LdpAtmLabel[%d] for LdpAsp\n", i);
17880 + return MPLS_DEC_ATMLBLERROR;
17882 + tempBuf += decodedSize;
17883 + totalSize += decodedSize;
17886 + return totalSize;
17888 +} /* End Mpls_decodeLdpAsp */
17891 + * Encode-decode for TLV
17892 + */
17894 +/*
17895 + * encode:
17896 + */
17897 +int Mpls_encodeLdpTlv(mplsLdpTlv_t * tlv, u_char * buff, int bufSize)
17899 + if (MPLS_TLVFIXLEN > bufSize) {
17900 + /* not enough room for label */
17901 + return MPLS_ENC_BUFFTOOSMALL;
17904 + tlv->flags.mark = htons(tlv->flags.mark);
17905 + tlv->length = htons(tlv->length);
17907 + MEM_COPY(buff, (u_char *) tlv, MPLS_TLVFIXLEN);
17909 + return MPLS_TLVFIXLEN;
17911 +} /* End: Mpls_encodeLdpTlv */
17913 +/*
17914 + * decode:
17915 + */
17916 +int Mpls_decodeLdpTlv(mplsLdpTlv_t * tlv, u_char * buff, int bufSize)
17918 + if (MPLS_TLVFIXLEN > bufSize) {
17919 + PRINT_ERR("Failed decoding TLV\n");
17920 + return MPLS_DEC_BUFFTOOSMALL;
17923 + MEM_COPY((u_char *) tlv, buff, MPLS_TLVFIXLEN);
17925 + tlv->flags.mark = ntohs(tlv->flags.mark);
17926 + tlv->length = ntohs(tlv->length);
17928 + return MPLS_TLVFIXLEN;
17930 +} /* End: Mpls_decodeLdpTlv */
17933 + * Encode-decode for CSP (common session param)
17934 + */
17936 +/*
17937 + * encode:
17938 + */
17939 +int Mpls_encodeLdpCsp(mplsLdpCspTlv_t * csp, u_char * buff, int bufSize)
17941 + int encodedSize = 0;
17942 + u_char *tempBuf = buff; /* no change for the buff ptr */
17943 + u_char *cspPtr;
17945 + if (MPLS_CSPFIXLEN + MPLS_TLVFIXLEN > bufSize) {
17946 + /* not enough room */
17947 + return MPLS_ENC_BUFFTOOSMALL;
17950 + cspPtr = (u_char *) csp;
17952 + /*
17953 + * encode for tlv
17954 + */
17955 + encodedSize = Mpls_encodeLdpTlv(&(csp->baseTlv), tempBuf, bufSize);
17956 + if (encodedSize < 0) {
17957 + PRINT_ERR("failed encoding the tlv in CSP\n");
17958 + return MPLS_ENC_TLVERROR;
17960 + tempBuf += encodedSize;
17961 + cspPtr += encodedSize;
17963 + /*
17964 + * encode for the rest of the Csp
17965 + */
17966 + csp->protocolVersion = htons(csp->protocolVersion);
17967 + csp->holdTime = htons(csp->holdTime);
17968 + csp->flags.mark = htons(csp->flags.mark);
17969 + csp->maxPduLen = htons(csp->maxPduLen);
17970 + csp->rcvLsrAddress = htonl(csp->rcvLsrAddress);
17971 + csp->rcvLsId = htons(csp->rcvLsId);
17973 + MEM_COPY(tempBuf, cspPtr, MPLS_CSPFIXLEN);
17975 + return (MPLS_CSPFIXLEN + MPLS_TLVFIXLEN);
17977 +} /* End: Mpls_encodeLdpCsp */
17979 +/*
17980 + * decode:
17981 + */
17982 +int Mpls_decodeLdpCsp(mplsLdpCspTlv_t * csp, u_char * buff, int bufSize)
17984 + u_char *cspPtr;
17986 + if (MPLS_CSPFIXLEN > bufSize) {
17987 + /* not enough data for Csp */
17988 + PRINT_ERR("failed decoding LdpCsp\n");
17989 + return MPLS_DEC_BUFFTOOSMALL;
17992 + cspPtr = (u_char *) csp;
17993 + cspPtr += MPLS_TLVFIXLEN; /* we want to point to the flags since the
17994 + tlv was decoded before we reach here */
17996 + /*
17997 + * decode for the rest of the Csp
17998 + */
17999 + MEM_COPY(cspPtr, buff, MPLS_CSPFIXLEN);
18001 + csp->protocolVersion = ntohs(csp->protocolVersion);
18002 + csp->holdTime = ntohs(csp->holdTime);
18003 + csp->flags.mark = ntohs(csp->flags.mark);
18004 + csp->maxPduLen = ntohs(csp->maxPduLen);
18005 + csp->rcvLsrAddress = ntohl(csp->rcvLsrAddress);
18006 + csp->rcvLsId = ntohs(csp->rcvLsId);
18008 + return MPLS_CSPFIXLEN;
18010 +} /* Mpls_decodeLdpCsp */
18013 + * Encode-decode for Fr Session Parameters
18014 + */
18016 +/*
18017 + * encode
18018 + */
18019 +int Mpls_encodeLdpFsp(mplsLdpFspTlv_t * frFsp, u_char * buff, int bufSize)
18021 + int encodedSize = 0;
18022 + u_short totalSize = 0;
18023 + u_char *tempBuf = buff; /* no change for the buff ptr */
18024 + u_int i, numLblRng;
18026 + /* get the size of the frAsp to be encoded and check it against
18027 + the buffer size */
18029 + if (MPLS_TLVFIXLEN + (int)(frFsp->baseTlv.length) > bufSize) {
18030 + /* not enough room */
18031 + return MPLS_ENC_BUFFTOOSMALL;
18034 + /*
18035 + * encode for tlv
18036 + */
18037 + encodedSize = Mpls_encodeLdpTlv(&(frFsp->baseTlv), tempBuf, bufSize);
18038 + if (encodedSize < 0) {
18039 + return MPLS_ENC_TLVERROR;
18041 + tempBuf += encodedSize;
18042 + totalSize += encodedSize;
18044 + /*
18045 + * encode for M + N + dir + res
18046 + */
18047 + numLblRng = frFsp->flags.flags.numLblRng;
18048 + frFsp->flags.flags.res = 0;
18049 + frFsp->flags.mark = htonl(frFsp->flags.mark);
18051 + MEM_COPY(tempBuf, (u_char *) & (frFsp->flags.mark), MPLS_FSPFIXLEN);
18052 + tempBuf += MPLS_FSPFIXLEN;
18053 + totalSize += MPLS_FSPFIXLEN;
18055 + /*
18056 + * encode for FR labels
18057 + */
18058 + for (i = 0; i < numLblRng; i++) {
18059 + encodedSize = Mpls_encodeLdpFrLblRng(&(frFsp->lblRngList[i]),
18060 + tempBuf, bufSize - totalSize);
18061 + if (encodedSize < 0) {
18062 + return MPLS_ENC_FSPLBLERROR;
18064 + tempBuf += encodedSize;
18065 + totalSize += encodedSize;
18068 + return totalSize;
18070 +} /* End: Mpls_encodeLdpFsp */
18072 +/*
18073 + * decode
18074 + */
18075 +int Mpls_decodeLdpFsp(mplsLdpFspTlv_t * frFsp, u_char * buff, int bufSize)
18077 + int decodedSize = 0;
18078 + u_short totalSize = 0;
18079 + u_char *tempBuf = buff; /* no change for the buff ptr */
18080 + u_int i;
18082 + if (MPLS_FSPFIXLEN > bufSize) {
18083 + /* the buffer does not contain even the required field */
18084 + PRINT_ERR("failed in decoding LdpFsp\n");
18085 + return MPLS_DEC_BUFFTOOSMALL;
18088 + /*
18089 + * decode for M + N + res
18090 + */
18091 + MEM_COPY((u_char *) & (frFsp->flags.mark), tempBuf, MPLS_FSPFIXLEN);
18092 + tempBuf += MPLS_FSPFIXLEN;
18093 + totalSize += MPLS_FSPFIXLEN;
18095 + frFsp->flags.mark = ntohl(frFsp->flags.mark);
18097 + /*
18098 + * decode for FR labels
18099 + */
18100 + for (i = 0; i < frFsp->flags.flags.numLblRng; i++) {
18101 + decodedSize = Mpls_decodeLdpFrLblRng(&(frFsp->lblRngList[i]),
18102 + tempBuf, bufSize - totalSize);
18103 + if (decodedSize < 0) {
18104 + PRINT_ERR("failed in decoding LdpFrLabel[%d] for LdpFsp\n", i);
18105 + return MPLS_DEC_FSPLBLERROR;
18107 + tempBuf += decodedSize;
18108 + totalSize += decodedSize;
18111 + return totalSize;
18113 +} /* End: Mpls_decodeLdpFsp */
18116 + * Encode-decode for INIT msg
18117 + */
18119 +/*
18120 + * encode for init message
18121 + */
18122 +int Mpls_encodeLdpInitMsg
18123 + (mplsLdpInitMsg_t * initMsg, u_char * buff, int bufSize) {
18124 + mplsLdpInitMsg_t initMsgCopy;
18125 + int encodedSize, totalSize;
18126 + u_char *tempBuf = buff; /* no change for the buff ptr */
18128 + initMsgCopy = *initMsg;
18129 + totalSize = 0;
18131 + /* check the length of the messageId + mandatory param +
18132 + optional param */
18133 + if ((int)(initMsgCopy.baseMsg.msgLength) + MPLS_TLVFIXLEN > bufSize) {
18134 + PRINT_ERR("failed to encode the init msg: BUFFER TOO SMALL\n");
18135 + return MPLS_ENC_BUFFTOOSMALL;
18138 + /*
18139 + * encode the base part of the pdu message
18140 + */
18141 + encodedSize = Mpls_encodeLdpBaseMsg(&(initMsgCopy.baseMsg), tempBuf, bufSize);
18142 + if (encodedSize < 0) {
18143 + return MPLS_ENC_BASEMSGERROR;
18145 + PRINT_OUT("Encode BaseMsg for init on %d bytes\n", encodedSize);
18146 + tempBuf += encodedSize;
18147 + totalSize += encodedSize;
18149 + /*
18150 + * encode the csp if any
18151 + */
18152 + if (initMsgCopy.cspExists) {
18153 + encodedSize = Mpls_encodeLdpCsp(&(initMsgCopy.csp),
18154 + tempBuf, bufSize - totalSize);
18155 + if (encodedSize < 0) {
18156 + return MPLS_ENC_CSPERROR;
18158 + PRINT_OUT("Encoded for CSP %d bytes\n", encodedSize);
18159 + tempBuf += encodedSize;
18160 + totalSize += encodedSize;
18163 + /*
18164 + * encode the asp if any
18165 + */
18166 + if (initMsgCopy.aspExists) {
18168 + encodedSize = Mpls_encodeLdpAsp(&(initMsgCopy.asp),
18169 + tempBuf, bufSize - totalSize);
18170 + if (encodedSize < 0) {
18171 + return MPLS_ENC_ASPERROR;
18173 + PRINT_OUT("Encoded for ASP %d bytes\n", encodedSize);
18174 + tempBuf += encodedSize;
18175 + totalSize += encodedSize;
18178 + /*
18179 + * encode the fsp if any
18180 + */
18181 + if (initMsgCopy.fspExists) {
18182 + encodedSize = Mpls_encodeLdpFsp(&(initMsgCopy.fsp),
18183 + tempBuf, bufSize - totalSize);
18184 + if (encodedSize < 0) {
18185 + return MPLS_ENC_FSPERROR;
18187 + tempBuf += encodedSize;
18188 + totalSize += encodedSize;
18191 + return totalSize;
18193 +} /* End: Mpls_encodeLdpInitMsg */
18195 +/*
18196 + * decode for unknown message
18197 + */
18198 +int Mpls_decodeLdpUnknownMsg
18199 + (mplsLdpUnknownMsg_t * msg, u_char * buff, int bufSize) {
18200 + int decodedSize = 0;
18201 + u_int totalSize = 0;
18202 + u_char *tempBuf = buff; /* no change for the buff ptr */
18204 + /*
18205 + * decode the base part of the pdu message
18206 + */
18207 + memset(msg, 0, sizeof(mplsLdpMsg_t));
18208 + decodedSize = Mpls_decodeLdpBaseMsg(&(msg->baseMsg), tempBuf, bufSize);
18209 + if (decodedSize < 0) {
18210 + return MPLS_DEC_BASEMSGERROR;
18212 + PRINT_OUT("Decode BaseMsg for unknown on %d bytes\n", decodedSize);
18214 + tempBuf += decodedSize;
18215 + totalSize += decodedSize;
18217 + if (bufSize - totalSize <= 0) {
18218 + /* nothing left for decoding */
18219 + PRINT_ERR("Init msg does not have anything beside base msg\n");
18220 + return totalSize;
18223 + if (msg->baseMsg.msgLength > MPLS_NOT_MAXSIZE) {
18224 + PRINT_ERR("Message is too big for unknow message buffer.\n");
18225 + return MPLS_DEC_BASEMSGERROR;
18228 + memcpy(msg->data, tempBuf, msg->baseMsg.msgLength);
18229 + decodedSize = msg->baseMsg.msgLength;
18231 + tempBuf += decodedSize;
18232 + totalSize += decodedSize;
18234 + PRINT_OUT("totalsize for Mpls_decodeLdpUnknowntMsg is %d\n", totalSize);
18236 + return totalSize;
18239 +/*
18240 + * decode for init message
18241 + */
18242 +int Mpls_decodeLdpInitMsg
18243 + (mplsLdpInitMsg_t * initMsg, u_char * buff, int bufSize) {
18244 + int decodedSize = 0;
18245 + u_int totalSize = 0;
18246 + u_int stopLength = 0;
18247 + u_char *tempBuf = buff; /* no change for the buff ptr */
18248 + u_int totalSizeParam = 0;
18249 + mplsLdpTlv_t tlvTemp;
18251 + /*
18252 + * decode the base part of the pdu message
18253 + */
18254 + memset(initMsg, 0, sizeof(mplsLdpInitMsg_t));
18255 + decodedSize = Mpls_decodeLdpBaseMsg(&(initMsg->baseMsg), tempBuf, bufSize);
18256 + if (decodedSize < 0) {
18257 + return MPLS_DEC_BASEMSGERROR;
18259 + PRINT_OUT("Decode BaseMsg for init on %d bytes\n", decodedSize);
18261 + if (initMsg->baseMsg.flags.flags.msgType != MPLS_INIT_MSGTYPE) {
18262 + PRINT_ERR("Not the right message type; expected init and got %x\n",
18263 + initMsg->baseMsg.flags.flags.msgType);
18264 + return MPLS_MSGTYPEERROR;
18266 + tempBuf += decodedSize;
18267 + totalSize += decodedSize;
18269 + if (bufSize - totalSize <= 0) {
18270 + /* nothing left for decoding */
18271 + PRINT_ERR("Init msg does not have anything beside base msg\n");
18272 + return totalSize;
18275 + PRINT_OUT("bufSize = %d, totalSize = %d, initMsg->baseMsg.msgLength = %d\n",
18276 + bufSize, totalSize, initMsg->baseMsg.msgLength);
18278 + /* Have to check the baseMsg.msgLength to know when to finish.
18279 + * We finsh when the totalSizeParam is >= to the base message length - the
18280 + * message id length (4)
18281 + */
18283 + stopLength = initMsg->baseMsg.msgLength - MPLS_MSGIDFIXLEN;
18284 + while (stopLength > totalSizeParam) {
18285 + /*
18286 + * decode the tlv to check what's next
18287 + */
18288 + decodedSize = Mpls_decodeLdpTlv(&tlvTemp, tempBuf, bufSize - totalSize);
18289 + if (decodedSize < 0) {
18290 + /* something wrong */
18291 + PRINT_ERR("INIT msg decode failed for tlv\n");
18292 + return MPLS_DEC_TLVERROR;
18295 + tempBuf += decodedSize;
18296 + totalSize += decodedSize;
18297 + totalSizeParam += decodedSize;
18299 + switch (tlvTemp.flags.flags.tBit) {
18300 + case MPLS_CSP_TLVTYPE:
18302 + decodedSize = Mpls_decodeLdpCsp(&(initMsg->csp),
18303 + tempBuf, bufSize - totalSize);
18304 + if (decodedSize < 0) {
18305 + PRINT_ERR("Failure when decoding Csp from init msg\n");
18306 + return MPLS_DEC_CSPERROR;
18308 + PRINT_OUT("Decoded for CSP %d bytes\n", decodedSize);
18309 + tempBuf += decodedSize;
18310 + totalSize += decodedSize;
18311 + totalSizeParam += decodedSize;
18312 + initMsg->cspExists = 1;
18313 + initMsg->csp.baseTlv = tlvTemp;
18314 + break;
18316 + case MPLS_ASP_TLVTYPE:
18318 + decodedSize = Mpls_decodeLdpAsp(&(initMsg->asp),
18319 + tempBuf, bufSize - totalSize);
18320 + if (decodedSize < 0) {
18321 + PRINT_ERR("Failure when decoding Asp from init msg\n");
18322 + return MPLS_DEC_ASPERROR;
18324 + PRINT_OUT("Decoded for ASP %d bytes\n", decodedSize);
18325 + tempBuf += decodedSize;
18326 + totalSize += decodedSize;
18327 + totalSizeParam += decodedSize;
18328 + initMsg->aspExists = 1;
18329 + initMsg->asp.baseTlv = tlvTemp;
18330 + break;
18332 + case MPLS_FSP_TLVTYPE:
18334 + decodedSize = Mpls_decodeLdpFsp(&(initMsg->fsp),
18335 + tempBuf, bufSize - totalSize);
18336 + if (decodedSize < 0) {
18337 + PRINT_ERR("Failure when decoding Fsp from init msg\n");
18338 + return MPLS_DEC_FSPERROR;
18340 + tempBuf += decodedSize;
18341 + totalSize += decodedSize;
18342 + totalSizeParam += decodedSize;
18343 + initMsg->fspExists = 1;
18344 + initMsg->fsp.baseTlv = tlvTemp;
18345 + break;
18347 + default:
18349 + PRINT_ERR("Found wrong tlv type while decoding init msg (%d)\n",
18350 + tlvTemp.flags.flags.tBit);
18351 + if (tlvTemp.flags.flags.uBit == 1) {
18352 + /* ignore the Tlv and continue processing */
18353 + tempBuf += tlvTemp.length;
18354 + totalSize += tlvTemp.length;
18355 + totalSizeParam += tlvTemp.length;
18356 + break;
18357 + } else {
18358 + /* drop the message; return error */
18359 + return MPLS_TLVTYPEERROR;
18362 + } /* switch type */
18364 + } /* while */
18366 + PRINT_OUT("totalsize for Mpls_decodeLdpInitMsg is %d\n", totalSize);
18368 + return totalSize;
18370 +} /* End: Mpls_decodeLdpInitMsg */
18373 + * Encode-decode for Fr Label Range
18374 + */
18376 +/*
18377 + * encode
18378 + */
18379 +int Mpls_encodeLdpFrLblRng
18380 + (mplsLdpFrLblRng_t * frLabel, u_char * buff, int bufSize) {
18381 + if (MPLS_FRLRGFIXLEN > bufSize) {
18382 + /* not enough room for label */
18383 + return MPLS_ENC_BUFFTOOSMALL;
18386 + frLabel->flags.flags.res_min = 0;
18387 + frLabel->flags.flags.res_max = 0;
18388 + frLabel->flags.mark[0] = htonl(frLabel->flags.mark[0]);
18389 + frLabel->flags.mark[1] = htonl(frLabel->flags.mark[1]);
18391 + MEM_COPY(buff, (u_char *) frLabel, MPLS_FRLRGFIXLEN);
18393 + return MPLS_FRLRGFIXLEN;
18395 +} /* End: Mpls_encodeLdpFrLblRng */
18397 +/*
18398 + * decode
18399 + */
18400 +int Mpls_decodeLdpFrLblRng
18401 + (mplsLdpFrLblRng_t * frLabel, u_char * buff, int bufSize) {
18402 + if (MPLS_FRLRGFIXLEN > bufSize) {
18403 + PRINT_ERR("failed decoding the Fr Lbl Rng\n");
18404 + return MPLS_DEC_BUFFTOOSMALL;
18407 + MEM_COPY((u_char *) frLabel, buff, MPLS_FRLRGFIXLEN);
18409 + frLabel->flags.mark[0] = ntohl(frLabel->flags.mark[0]);
18410 + frLabel->flags.mark[1] = ntohl(frLabel->flags.mark[1]);
18412 + return MPLS_FRLRGFIXLEN;
18414 +} /* End: Mpls_decodeLdpFrLblRng */
18417 + * Encode-decode for NOTIFICATION msg
18418 + */
18420 +/*
18421 + * encode for notification message
18422 + */
18423 +int Mpls_encodeLdpNotMsg(mplsLdpNotifMsg_t * notMsg, u_char * buff, int bufSize)
18425 + mplsLdpNotifMsg_t notMsgCopy;
18426 + int encodedSize = 0;
18427 + u_int totalSize = 0;
18428 + u_char *tempBuf = buff; /* no change for the buff ptr */
18430 + /* check the length of the messageId + mandatory param +
18431 + optional param */
18432 + if ((int)(notMsg->baseMsg.msgLength) + MPLS_TLVFIXLEN > bufSize) {
18433 + PRINT_ERR("failed to encode the not msg: BUFFER TOO SMALL\n");
18434 + return MPLS_ENC_BUFFTOOSMALL;
18437 + notMsgCopy = *notMsg;
18439 + /*
18440 + * encode the base part of the pdu message
18441 + */
18442 + encodedSize = Mpls_encodeLdpBaseMsg(&(notMsgCopy.baseMsg), tempBuf, bufSize);
18443 + if (encodedSize < 0) {
18444 + return MPLS_ENC_BASEMSGERROR;
18446 + PRINT_OUT("Encode BaseMsg for not on %d bytes\n", encodedSize);
18448 + tempBuf += encodedSize;
18449 + totalSize += encodedSize;
18451 + if (notMsgCopy.statusTlvExists) {
18452 + encodedSize = Mpls_encodeLdpStatus(&(notMsgCopy.status),
18453 + tempBuf, bufSize - totalSize);
18454 + if (encodedSize < 0) {
18455 + return MPLS_ENC_STATUSERROR;
18457 + PRINT_OUT("Encoded for STATUS %d bytes\n", encodedSize);
18458 + tempBuf += encodedSize;
18459 + totalSize += encodedSize;
18461 + if (notMsgCopy.exStatusTlvExists) {
18462 + encodedSize = Mpls_encodeLdpExStatus(&(notMsgCopy.exStatus),
18463 + tempBuf, bufSize - totalSize);
18464 + if (encodedSize < 0) {
18465 + return MPLS_ENC_EXSTATERROR;
18467 + PRINT_OUT("Encoded for EXTENDED STATUS %d bytes\n", encodedSize);
18468 + tempBuf += encodedSize;
18469 + totalSize += encodedSize;
18471 + if (notMsgCopy.retPduTlvExists) {
18472 + encodedSize = Mpls_encodeLdpRetPdu(&(notMsgCopy.retPdu),
18473 + tempBuf, bufSize - totalSize);
18474 + if (encodedSize < 0) {
18475 + return MPLS_ENC_RETPDUERROR;
18477 + PRINT_OUT("Encoded for RET PDU %d bytes\n", encodedSize);
18478 + tempBuf += encodedSize;
18479 + totalSize += encodedSize;
18481 + if (notMsgCopy.retMsgTlvExists) {
18482 + encodedSize = Mpls_encodeLdpRetMsg(&(notMsgCopy.retMsg),
18483 + tempBuf, bufSize - totalSize);
18484 + if (encodedSize < 0) {
18485 + return MPLS_ENC_RETMSGERROR;
18487 + PRINT_OUT("Encoded for RET MSG %d bytes\n", encodedSize);
18488 + tempBuf += encodedSize;
18489 + totalSize += encodedSize;
18491 + if (notMsgCopy.lspidTlvExists) {
18492 + encodedSize = Mpls_encodeLdpLspIdTlv(&(notMsgCopy.lspidTlv),
18493 + tempBuf, bufSize - totalSize);
18494 + if (encodedSize < 0) {
18495 + return MPLS_ENC_LSPIDERROR;
18497 + PRINT_OUT("Encoded for LSPID Tlv %d bytes\n", encodedSize);
18498 + tempBuf += encodedSize;
18499 + totalSize += encodedSize;
18502 + return totalSize;
18504 +} /* End: Mpls_encodeLdpNotMsg */
18506 +/*
18507 + * decode for notification message
18508 + */
18509 +int Mpls_decodeLdpNotMsg(mplsLdpNotifMsg_t * notMsg, u_char * buff, int bufSize)
18511 + int decodedSize = 0;
18512 + u_int totalSize = 0;
18513 + u_int stopLength = 0;
18514 + u_int totalSizeParam = 0;
18515 + u_char *tempBuf = buff; /* no change for the buff ptr */
18516 + mplsLdpTlv_t tlvTemp;
18518 + /*
18519 + * decode the base part of the pdu message
18520 + */
18521 + memset(notMsg, 0, sizeof(mplsLdpNotifMsg_t));
18522 + decodedSize = Mpls_decodeLdpBaseMsg(&(notMsg->baseMsg), tempBuf, bufSize);
18523 + if (decodedSize < 0) {
18524 + return MPLS_DEC_BASEMSGERROR;
18526 + PRINT_OUT("Decode BaseMsg for not on %d bytes\n", decodedSize);
18528 + if (notMsg->baseMsg.flags.flags.msgType != MPLS_NOT_MSGTYPE) {
18529 + PRINT_ERR("Not the right message type; expected not and got %x\n",
18530 + notMsg->baseMsg.flags.flags.msgType);
18531 + return MPLS_MSGTYPEERROR;
18534 + tempBuf += decodedSize;
18535 + totalSize += decodedSize;
18537 + if (bufSize - totalSize <= 0) {
18538 + /* nothing left for decoding */
18539 + PRINT_ERR("Not msg does not have anything beside base msg\n");
18540 + return totalSize;
18543 + PRINT_OUT("bufSize = %d, totalSize = %d, notMsg->baseMsg.msgLength = %d\n",
18544 + bufSize, totalSize, notMsg->baseMsg.msgLength);
18546 + /* Have to check the baseMsg.msgLength to know when to finish.
18547 + * We finsh when the totalSizeParam is >= to the base message length - the
18548 + * message id length (4)
18549 + */
18551 + stopLength = notMsg->baseMsg.msgLength - MPLS_MSGIDFIXLEN;
18552 + while (stopLength > totalSizeParam) {
18553 + /*
18554 + * decode the tlv to check what's next
18555 + */
18556 + memset(&tlvTemp, 0, MPLS_TLVFIXLEN);
18557 + decodedSize = Mpls_decodeLdpTlv(&tlvTemp, tempBuf, bufSize - totalSize);
18558 + if (decodedSize < 0) {
18559 + /* something wrong */
18560 + PRINT_ERR("NOT msg decode failed for tlv\n");
18561 + return MPLS_DEC_TLVERROR;
18564 + tempBuf += decodedSize;
18565 + totalSize += decodedSize;
18566 + totalSizeParam += decodedSize;
18568 + switch (tlvTemp.flags.flags.tBit) {
18569 + case MPLS_NOT_ST_TLVTYPE:
18571 + decodedSize = Mpls_decodeLdpStatus(&(notMsg->status),
18572 + tempBuf, bufSize - totalSize);
18573 + if (decodedSize < 0) {
18574 + PRINT_ERR("Failure when decoding Status from not msg\n");
18575 + return MPLS_DEC_STATUSERROR;
18577 + PRINT_OUT("Decoded for STATUS %d bytes\n", decodedSize);
18578 + tempBuf += decodedSize;
18579 + totalSize += decodedSize;
18580 + totalSizeParam += decodedSize;
18582 + notMsg->statusTlvExists = 1;
18583 + notMsg->status.baseTlv = tlvTemp;
18584 + break;
18586 + case MPLS_NOT_ES_TLVTYPE:
18588 + decodedSize = Mpls_decodeLdpExStatus(&(notMsg->exStatus),
18589 + tempBuf, bufSize - totalSize);
18590 + if (decodedSize < 0) {
18591 + PRINT_ERR("Failure when decoding Extended Status from not msg\n");
18592 + return MPLS_DEC_EXSTATERROR;
18594 + PRINT_OUT("Decoded for EX_STATUS %d bytes\n", decodedSize);
18595 + tempBuf += decodedSize;
18596 + totalSize += decodedSize;
18597 + totalSizeParam += decodedSize;
18599 + notMsg->exStatusTlvExists = 1;
18600 + notMsg->exStatus.baseTlv = tlvTemp;
18601 + break;
18603 + case MPLS_NOT_RP_TLVTYPE:
18605 + decodedSize = Mpls_decodeLdpRetPdu(&(notMsg->retPdu),
18606 + tempBuf, bufSize - totalSize, tlvTemp.length);
18607 + if (decodedSize < 0) {
18608 + PRINT_ERR("Failure when decoding Returned PDU from not msg\n");
18609 + return MPLS_DEC_RETPDUERROR;
18611 + PRINT_OUT("Decoded for RET_PDU %d bytes\n", decodedSize);
18612 + tempBuf += decodedSize;
18613 + totalSize += decodedSize;
18614 + totalSizeParam += decodedSize;
18616 + notMsg->retPduTlvExists = 1;
18617 + notMsg->retPdu.baseTlv = tlvTemp;
18618 + break;
18620 + case MPLS_NOT_RM_TLVTYPE:
18622 + decodedSize = Mpls_decodeLdpRetMsg(&(notMsg->retMsg),
18623 + tempBuf, bufSize - totalSize, tlvTemp.length);
18624 + if (decodedSize < 0) {
18625 + PRINT_ERR("Failure when decoding Returned MSG from not msg\n");
18626 + return MPLS_DEC_RETMSGERROR;
18628 + PRINT_OUT("Decoded for RET_MSG %d bytes\n", decodedSize);
18629 + tempBuf += decodedSize;
18630 + totalSize += decodedSize;
18631 + totalSizeParam += decodedSize;
18633 + notMsg->retMsgTlvExists = 1;
18634 + notMsg->retMsg.baseTlv = tlvTemp;
18635 + break;
18637 + case MPLS_LSPID_TLVTYPE:
18639 + decodedSize = Mpls_decodeLdpLspIdTlv(&(notMsg->lspidTlv),
18640 + tempBuf, bufSize - totalSize);
18641 + if (decodedSize < 0) {
18642 + PRINT_ERR("Failure when dec LSPID tlv from Not msg\n");
18643 + return MPLS_DEC_LSPIDERROR;
18645 + PRINT_OUT("Decoded for lspid tlv %d bytes\n", decodedSize);
18646 + tempBuf += decodedSize;
18647 + totalSize += decodedSize;
18648 + totalSizeParam += decodedSize;
18650 + notMsg->lspidTlvExists = 1;
18651 + notMsg->lspidTlv.baseTlv = tlvTemp;
18652 + break;
18654 + default:
18656 + PRINT_ERR("Found wrong tlv type while decoding not msg (%d)\n",
18657 + tlvTemp.flags.flags.tBit);
18658 + if (tlvTemp.flags.flags.uBit == 1) {
18659 + /* ignore the Tlv and continue processing */
18660 + tempBuf += tlvTemp.length;
18661 + totalSize += tlvTemp.length;
18662 + totalSizeParam += tlvTemp.length;
18663 + break;
18664 + } else {
18665 + /* drop the message; return error */
18666 + return MPLS_TLVTYPEERROR;
18669 + } /* switch type */
18671 + } /* while */
18673 + PRINT_OUT("totalsize for Mpls_decodeLdpNotMsg is %d\n", totalSize);
18675 + return totalSize;
18677 +} /* End: Mpls_decodeLdpNotMsg */
18680 + * Encode-decode for Status TLV
18681 + */
18683 +/*
18684 + * encode:
18685 + */
18686 +int Mpls_encodeLdpStatus
18687 + (mplsLdpStatusTlv_t * status, u_char * buff, int bufSize) {
18688 + int encodedSize = 0;
18689 + u_char *tempBuf = buff; /* no change for the buff ptr */
18690 + u_char *statusPtr;
18692 + if (MPLS_STATUSFIXLEN + MPLS_TLVFIXLEN > bufSize) {
18693 + /* not enough room */
18694 + return MPLS_ENC_BUFFTOOSMALL;
18697 + /*
18698 + * encode for tlv
18699 + */
18700 + encodedSize = Mpls_encodeLdpTlv(&(status->baseTlv), tempBuf, bufSize);
18701 + if (encodedSize < 0) {
18702 + PRINT_ERR("failed encoding the tlv in STATUS\n");
18703 + return MPLS_ENC_TLVERROR;
18706 + statusPtr = (u_char *) status;
18707 + tempBuf += encodedSize;
18708 + statusPtr += encodedSize;
18710 + /*
18711 + * encode for the rest of the Status
18712 + */
18713 + status->flags.mark = htonl(status->flags.mark);
18714 + status->msgId = htonl(status->msgId);
18715 + status->msgType = htons(status->msgType);
18717 + MEM_COPY(tempBuf, statusPtr, MPLS_STATUSFIXLEN);
18719 + return (MPLS_STATUSFIXLEN + MPLS_TLVFIXLEN);
18721 +} /* End: Mpls_encodeLdpStatus */
18723 +/*
18724 + * decode:
18725 + */
18726 +int Mpls_decodeLdpStatus
18727 + (mplsLdpStatusTlv_t * status, u_char * buff, int bufSize) {
18728 + u_char *statusPtr;
18730 + if (MPLS_STATUSFIXLEN > bufSize) {
18731 + /* not enough data for Status */
18732 + PRINT_ERR("failed decoding Status\n");
18733 + return MPLS_DEC_BUFFTOOSMALL;
18736 + statusPtr = (u_char *) status;
18737 + statusPtr += MPLS_TLVFIXLEN; /* we want to point to the flags since the
18738 + tlv was decoded before we reach here */
18740 + /*
18741 + * decode for the rest of the Status
18742 + */
18743 + MEM_COPY(statusPtr, buff, MPLS_STATUSFIXLEN);
18745 + status->flags.mark = ntohl(status->flags.mark);
18746 + status->msgId = ntohl(status->msgId);
18747 + status->msgType = ntohs(status->msgType);
18749 + return MPLS_STATUSFIXLEN;
18751 +} /* End: Mpls_decodeLdpStatus */
18754 + * Encode-decode for Extended Status TLV
18755 + */
18757 +/*
18758 + * encode:
18759 + */
18760 +int Mpls_encodeLdpExStatus
18761 + (mplsLdpExStatusTlv_t * status, u_char * buff, int bufSize) {
18762 + int encodedSize = 0;
18763 + u_char *tempBuf = buff; /* no change for the buff ptr */
18765 + if (MPLS_EXSTATUSLEN + MPLS_TLVFIXLEN > bufSize) {
18766 + /* not enough room */
18767 + return MPLS_ENC_BUFFTOOSMALL;
18770 + /*
18771 + * encode for tlv
18772 + */
18773 + encodedSize = Mpls_encodeLdpTlv(&(status->baseTlv), tempBuf, bufSize);
18774 + if (encodedSize < 0) {
18775 + PRINT_ERR("failed encoding the tlv in EX_STATUS\n");
18776 + return MPLS_ENC_TLVERROR;
18778 + tempBuf += encodedSize;
18780 + status->value = htonl(status->value);
18782 + MEM_COPY(tempBuf, (u_char *) & (status->value), sizeof(u_int));
18784 + return (MPLS_EXSTATUSLEN + MPLS_TLVFIXLEN);
18786 +} /* End: Mpls_encodeLdpExStatus */
18788 +/*
18789 + * decode:
18790 + */
18791 +int Mpls_decodeLdpExStatus
18792 + (mplsLdpExStatusTlv_t * status, u_char * buff, int bufSize) {
18793 + if (MPLS_EXSTATUSLEN > bufSize) {
18794 + /* not enough data for ExStatus */
18795 + PRINT_ERR("failed decoding ExStatus\n");
18796 + return MPLS_DEC_BUFFTOOSMALL;
18799 + /*
18800 + * decode for the rest of the Status
18801 + */
18802 + MEM_COPY(&(status->value), buff, MPLS_EXSTATUSLEN);
18804 + status->value = ntohl(status->value);
18806 + return MPLS_EXSTATUSLEN;
18808 +} /* End: Mpls_decodeLdpExStatus */
18811 + * Encode-decode for Return PDU TLV
18812 + */
18814 +/*
18815 + * encode:
18816 + */
18817 +int Mpls_encodeLdpRetPdu
18818 + (mplsLdpRetPduTlv_t * retPdu, u_char * buff, int bufSize) {
18819 + int encodedSize = 0;
18820 + u_char *tempBuf = buff; /* no change for the buff ptr */
18821 + u_short tempLength; /* to store the tlv length for
18823 + later use */
18825 + if (MPLS_TLVFIXLEN + (int)(retPdu->baseTlv.length) > bufSize) {
18826 + /* not enough room */
18827 + return MPLS_ENC_BUFFTOOSMALL;
18830 + tempLength = retPdu->baseTlv.length;
18831 + /*
18832 + * encode for tlv
18833 + */
18834 + encodedSize = Mpls_encodeLdpTlv(&(retPdu->baseTlv), tempBuf, bufSize);
18835 + if (encodedSize < 0) {
18836 + PRINT_ERR("failed encoding the tlv in RET_PDU\n");
18837 + return MPLS_ENC_TLVERROR;
18839 + tempBuf += encodedSize;
18841 + /*
18842 + * encode the data of the ret pdu
18843 + */
18845 + encodedSize = Mpls_encodeLdpMsgHeader(&(retPdu->headerTlv),
18846 + tempBuf, bufSize - encodedSize);
18847 + if (encodedSize < 0) {
18848 + PRINT_ERR("failed encoding the header Tlv in RET_PDU\n");
18849 + return MPLS_ENC_HDRTLVERROR;
18851 + tempBuf += encodedSize;
18853 + MEM_COPY(tempBuf, retPdu->data, tempLength);
18855 + return (MPLS_TLVFIXLEN + tempLength);
18857 +} /* End: Mpls_encodeLdpRetPdu */
18859 +/*
18860 + * decode:
18861 + */
18862 +int Mpls_decodeLdpRetPdu
18863 + (mplsLdpRetPduTlv_t * retPdu, u_char * buff, int bufSize, u_short tlvLength) {
18864 + u_char *tempBuf = buff; /* no change for the buff ptr */
18865 + int decodedSize;
18867 + if ((int)tlvLength > bufSize) {
18868 + /* not enough data for ExStatus */
18869 + PRINT_ERR("failed decoding Ret pdu\n");
18870 + return MPLS_DEC_BUFFTOOSMALL;
18873 + /*
18874 + * decode data for ret pdu
18875 + */
18876 + decodedSize = Mpls_decodeLdpMsgHeader(&(retPdu->headerTlv), tempBuf, bufSize);
18877 + if (decodedSize < 0) {
18878 + PRINT_ERR("failed decoding the header Tlv in RET_PDU\n");
18879 + return MPLS_DEC_HDRTLVERROR;
18881 + tempBuf += decodedSize;
18883 + MEM_COPY(retPdu->data, tempBuf, tlvLength);
18885 + return tlvLength;
18887 +} /* End: Mpls_decodeLdpRetPdu */
18890 + * Encode-decode for Return Msg TLV
18891 + */
18893 +/*
18894 + * encode:
18895 + */
18896 +int Mpls_encodeLdpRetMsg
18897 + (mplsLdpRetMsgTlv_t * retMsg, u_char * buff, int bufSize) {
18898 + u_char *retMsgPtr;
18899 + int encodedSize = 0;
18900 + u_char *tempBuf = buff; /* no change for the buff ptr */
18901 + u_short tempLength; /* to store the tlv length for
18903 + later use */
18905 + if (MPLS_TLVFIXLEN + (int)(retMsg->baseTlv.length) > bufSize) {
18906 + /* not enough room */
18907 + return MPLS_ENC_BUFFTOOSMALL;
18910 + tempLength = retMsg->baseTlv.length;
18911 + /*
18912 + * encode for tlv
18913 + */
18914 + encodedSize = Mpls_encodeLdpTlv(&(retMsg->baseTlv), tempBuf, bufSize);
18915 + if (encodedSize < 0) {
18916 + PRINT_ERR("failed encoding the tlv in RET_MSG\n");
18917 + return MPLS_ENC_TLVERROR;
18920 + retMsgPtr = (u_char *) retMsg;
18921 + tempBuf += encodedSize;
18922 + retMsgPtr += encodedSize;
18924 + /*
18925 + * encode the data of the ret pdu
18926 + */
18928 + retMsg->msgType = htons(retMsg->msgType);
18929 + retMsg->msgLength = htons(retMsg->msgLength);
18931 + MEM_COPY(tempBuf, retMsgPtr, tempLength);
18933 + return (MPLS_TLVFIXLEN + tempLength);
18935 +} /* End: Mpls_encodeLdpRetMsg */
18937 +/*
18938 + * decode:
18939 + */
18940 +int Mpls_decodeLdpRetMsg
18941 + (mplsLdpRetMsgTlv_t * retMsg, u_char * buff, int bufSize, u_short tlvLength) {
18942 + u_char *tempBuf = buff; /* no change for the buff ptr */
18943 + u_char *retMsgPtr;
18945 + if ((int)tlvLength > bufSize) {
18946 + /* not enough data for ExStatus */
18947 + PRINT_ERR("failed decoding Ret msg\n");
18948 + return MPLS_DEC_BUFFTOOSMALL;
18950 + retMsgPtr = (u_char *) retMsg;
18951 + retMsgPtr += MPLS_TLVFIXLEN;
18953 + /*
18954 + * decode data for ret msg
18955 + */
18956 + MEM_COPY(retMsgPtr, tempBuf, tlvLength);
18958 + retMsg->msgType = ntohs(retMsg->msgType);
18959 + retMsg->msgLength = ntohs(retMsg->msgLength);
18961 + return tlvLength;
18963 +} /* End: Mpls_decodeLdpRetMsg */
18966 + * Encode-decode for HELLO msg
18967 + */
18969 +/*
18970 + * encode for HELLO message
18971 + */
18972 +int Mpls_encodeLdpHelloMsg
18973 + (mplsLdpHelloMsg_t * helloMsg, u_char * buff, int bufSize) {
18974 + mplsLdpHelloMsg_t helloMsgCopy;
18975 + int encodedSize = 0;
18976 + u_int totalSize = 0;
18977 + u_char *tempBuf = buff; /* no change for the buff ptr */
18979 + /* check the length of the messageId + mandatory param +
18980 + optional param */
18981 + if ((int)(helloMsg->baseMsg.msgLength) + MPLS_TLVFIXLEN > bufSize) {
18982 + PRINT_ERR("failed to encode the hello msg: BUFFER TOO SMALL\n");
18983 + return MPLS_ENC_BUFFTOOSMALL;
18986 + helloMsgCopy = *helloMsg;
18988 + /*
18989 + * encode the base part of the pdu message
18990 + */
18991 + encodedSize = Mpls_encodeLdpBaseMsg(&(helloMsgCopy.baseMsg),
18992 + tempBuf, bufSize);
18993 + if (encodedSize < 0) {
18994 + return MPLS_ENC_BASEMSGERROR;
18996 + PRINT_OUT("Encode BaseMsg for hello on %d bytes\n", encodedSize);
18997 + tempBuf += encodedSize;
18998 + totalSize += encodedSize;
19000 + /*
19001 + * encode the status tlv if any
19002 + */
19003 + if (helloMsgCopy.chpTlvExists) {
19004 + encodedSize = Mpls_encodeLdpChp(&(helloMsgCopy.chp),
19005 + tempBuf, bufSize - totalSize);
19006 + if (encodedSize < 0) {
19007 + return MPLS_ENC_CHPERROR;
19009 + PRINT_OUT("Encoded for CHP %d bytes\n", encodedSize);
19010 + tempBuf += encodedSize;
19011 + totalSize += encodedSize;
19013 + if (helloMsgCopy.trAdrTlvExists) {
19014 + encodedSize = Mpls_encodeLdpTrAdr(&(helloMsgCopy.trAdr),
19015 + tempBuf, bufSize - totalSize);
19016 + if (encodedSize < 0) {
19017 + return MPLS_ENC_TRADRERROR;
19019 + PRINT_OUT("Encoded for TR ADDR %d bytes\n", encodedSize);
19020 + tempBuf += encodedSize;
19021 + totalSize += encodedSize;
19023 + if (helloMsgCopy.csnTlvExists) {
19024 + encodedSize = Mpls_encodeLdpCsn(&(helloMsgCopy.csn),
19025 + tempBuf, bufSize - totalSize);
19026 + if (encodedSize < 0) {
19027 + return MPLS_ENC_CSNERROR;
19029 + PRINT_OUT("Encoded for CSN %d bytes\n", encodedSize);
19030 + tempBuf += encodedSize;
19031 + totalSize += encodedSize;
19034 + return totalSize;
19036 +} /* End: Mpls_encodeLdpHelloMsg */
19038 +/*
19039 + * decode for HELLO message
19040 + */
19041 +int Mpls_decodeLdpHelloMsg
19042 + (mplsLdpHelloMsg_t * helloMsg, u_char * buff, int bufSize) {
19043 + int decodedSize = 0;
19044 + u_int totalSize = 0;
19045 + u_int stopLength = 0;
19046 + u_int totalSizeParam = 0;
19047 + u_char *tempBuf = buff; /* no change for the buff ptr */
19048 + mplsLdpTlv_t tlvTemp;
19050 + /*
19051 + * decode the base part of the pdu message
19052 + */
19053 + memset(helloMsg, 0, sizeof(mplsLdpHelloMsg_t));
19054 + decodedSize = Mpls_decodeLdpBaseMsg(&(helloMsg->baseMsg), tempBuf, bufSize);
19055 + if (decodedSize < 0) {
19056 + return MPLS_DEC_BASEMSGERROR;
19058 + PRINT_OUT("Decode BaseMsg for hello on %d bytes\n", decodedSize);
19060 + if (helloMsg->baseMsg.flags.flags.msgType != MPLS_HELLO_MSGTYPE) {
19061 + PRINT_ERR("Not the right message type; expected hello and got %x\n",
19062 + helloMsg->baseMsg.flags.flags.msgType);
19063 + return MPLS_MSGTYPEERROR;
19066 + tempBuf += decodedSize;
19067 + totalSize += decodedSize;
19069 + if (bufSize - totalSize <= 0) {
19070 + /* nothing left for decoding */
19071 + PRINT_ERR("Hello msg does not have anything beside base msg\n");
19072 + return totalSize;
19075 + PRINT_OUT("bufSize = %d, totalSize = %d, helloMsg->baseMsg.msgLength = %d\n",
19076 + bufSize, totalSize, helloMsg->baseMsg.msgLength);
19078 + /* Have to check the baseMsg.msgLength to know when to finish.
19079 + * We finsh when the totalSizeParam is >= to the base message length - the
19080 + * message id length (4)
19081 + */
19083 + stopLength = helloMsg->baseMsg.msgLength - MPLS_MSGIDFIXLEN;
19084 + while (stopLength > totalSizeParam) {
19085 + /*
19086 + * decode the tlv to check what's next
19087 + */
19088 + memset(&tlvTemp, 0, MPLS_TLVFIXLEN);
19089 + decodedSize = Mpls_decodeLdpTlv(&tlvTemp, tempBuf, bufSize - totalSize);
19090 + if (decodedSize < 0) {
19091 + /* something wrong */
19092 + PRINT_ERR("NOT msg decode failed for tlv\n");
19093 + return MPLS_DEC_TLVERROR;
19096 + tempBuf += decodedSize;
19097 + totalSize += decodedSize;
19098 + totalSizeParam += decodedSize;
19100 + switch (tlvTemp.flags.flags.tBit) {
19101 + case MPLS_CHP_TLVTYPE:
19103 + decodedSize = Mpls_decodeLdpChp(&(helloMsg->chp),
19104 + tempBuf, bufSize - totalSize);
19105 + if (decodedSize < 0) {
19106 + PRINT_ERR("Failure when decoding Chp from hello msg\n");
19107 + return MPLS_DEC_CHPERROR;
19109 + PRINT_OUT("Decoded for CHP %d bytes\n", decodedSize);
19110 + tempBuf += decodedSize;
19111 + totalSize += decodedSize;
19112 + totalSizeParam += decodedSize;
19114 + helloMsg->chpTlvExists = 1;
19115 + helloMsg->chp.baseTlv = tlvTemp;
19116 + break;
19118 + case MPLS_TRADR_TLVTYPE:
19120 + decodedSize = Mpls_decodeLdpTrAdr(&(helloMsg->trAdr),
19121 + tempBuf, bufSize - totalSize);
19122 + if (decodedSize < 0) {
19123 + PRINT_ERR("Failure when decoding TrAdr from hello msg\n");
19124 + return MPLS_DEC_TRADRERROR;
19126 + PRINT_OUT("Decoded for TrAdr %d bytes\n", decodedSize);
19127 + tempBuf += decodedSize;
19128 + totalSize += decodedSize;
19129 + totalSizeParam += decodedSize;
19131 + helloMsg->trAdrTlvExists = 1;
19132 + helloMsg->trAdr.baseTlv = tlvTemp;
19133 + break;
19135 + case MPLS_CSN_TLVTYPE:
19137 + decodedSize = Mpls_decodeLdpCsn(&(helloMsg->csn),
19138 + tempBuf, bufSize - totalSize);
19139 + if (decodedSize < 0) {
19140 + PRINT_ERR("Failure when decoding Csn from hello msg\n");
19141 + return MPLS_DEC_CSNERROR;
19143 + PRINT_OUT("Decoded for CSN %d bytes\n", decodedSize);
19144 + tempBuf += decodedSize;
19145 + totalSize += decodedSize;
19146 + totalSizeParam += decodedSize;
19148 + helloMsg->csnTlvExists = 1;
19149 + helloMsg->csn.baseTlv = tlvTemp;
19150 + break;
19152 + default:
19154 + PRINT_ERR("Found wrong tlv type while decoding hello msg (%d)\n",
19155 + tlvTemp.flags.flags.tBit);
19156 + if (tlvTemp.flags.flags.uBit == 1) {
19157 + /* ignore the Tlv and continue processing */
19158 + tempBuf += tlvTemp.length;
19159 + totalSize += tlvTemp.length;
19160 + totalSizeParam += tlvTemp.length;
19161 + break;
19162 + } else {
19163 + /* drop the message; return error */
19164 + return MPLS_TLVTYPEERROR;
19167 + } /* switch type */
19169 + } /* while */
19171 + PRINT_OUT("totalsize for Mpls_decodeLdpHelloMsg is %d\n", totalSize);
19173 + return totalSize;
19175 +} /* End: Mpls_decodeLdpHelloMsg */
19177 +/*
19178 + * Encode for Common Hello Parameters TLV
19179 + */
19182 + * encode
19183 + */
19184 +int Mpls_encodeLdpChp(mplsLdpChpTlv_t * chp, u_char * buff, int bufSize)
19186 + int encodedSize = 0;
19187 + u_char *tempBuf = buff; /* no change for the buff ptr */
19188 + u_char *chpPtr;
19190 + /* get the size of the chp to be encoded and check it against
19191 + the buffer size */
19193 + if (MPLS_TLVFIXLEN + MPLS_CHPFIXLEN > bufSize) {
19194 + /* not enough room */
19195 + return MPLS_ENC_BUFFTOOSMALL;
19198 + /*
19199 + * encode for tlv
19200 + */
19201 + encodedSize = Mpls_encodeLdpTlv(&(chp->baseTlv), tempBuf, MPLS_TLVFIXLEN);
19202 + if (encodedSize < 0) {
19203 + return MPLS_ENC_TLVERROR;
19206 + chpPtr = (u_char *) chp;
19207 + tempBuf += encodedSize;
19208 + chpPtr += encodedSize;
19210 + /*
19211 + * encode for hold time + T + R + res
19212 + */
19213 + chp->flags.flags.res = 0;
19214 + chp->flags.mark = htons(chp->flags.mark);
19215 + chp->holdTime = htons(chp->holdTime);
19217 + MEM_COPY(tempBuf, chpPtr, MPLS_CHPFIXLEN);
19219 + return (MPLS_TLVFIXLEN + MPLS_CHPFIXLEN);
19221 +} /* End: Mpls_encodeLdpChp */
19223 +/*
19224 + * decode
19225 + */
19226 +int Mpls_decodeLdpChp(mplsLdpChpTlv_t * chp, u_char * buff, int bufSize)
19228 + u_char *chpPtr;
19230 + if (MPLS_CHPFIXLEN > bufSize) {
19231 + /* not enough data for Chp */
19232 + PRINT_ERR("failed decoding hello Chp\n");
19233 + return MPLS_DEC_BUFFTOOSMALL;
19236 + chpPtr = (u_char *) chp;
19237 + chpPtr += MPLS_TLVFIXLEN; /* we want to point to the flags since the
19238 + tlv was decoded before we reach here */
19240 + /*
19241 + * decode for the rest of the Chp
19242 + */
19243 + MEM_COPY(chpPtr, buff, MPLS_CHPFIXLEN);
19245 + chp->holdTime = ntohs(chp->holdTime);
19246 + chp->flags.mark = ntohs(chp->flags.mark);
19248 + return MPLS_CHPFIXLEN;
19250 +} /* End: Mpls_decodeLdpChp */
19252 +/*
19253 + * Encode for Configuration Sequence Number TLV
19254 + */
19257 + * encode
19258 + */
19259 +int Mpls_encodeLdpCsn(mplsLdpCsnTlv_t * csn, u_char * buff, int bufSize)
19261 + int encodedSize = 0;
19262 + u_char *tempBuf = buff; /* no change for the buff ptr */
19264 + if (MPLS_CSNFIXLEN + MPLS_TLVFIXLEN > bufSize) {
19265 + /* not enough room */
19266 + return MPLS_ENC_BUFFTOOSMALL;
19269 + /*
19270 + * encode for tlv
19271 + */
19272 + encodedSize = Mpls_encodeLdpTlv(&(csn->baseTlv), tempBuf, bufSize);
19273 + if (encodedSize < 0) {
19274 + PRINT_ERR("failed encoding the tlv in hello Csn\n");
19275 + return MPLS_ENC_TLVERROR;
19277 + tempBuf += encodedSize;
19279 + csn->seqNumber = htonl(csn->seqNumber);
19281 + MEM_COPY(tempBuf, (u_char *) & (csn->seqNumber), MPLS_CSNFIXLEN);
19283 + return (MPLS_CSNFIXLEN + MPLS_TLVFIXLEN);
19285 +} /* End: Mpls_encodeLdpCsn */
19287 +/*
19288 + * decode
19289 + */
19290 +int Mpls_decodeLdpCsn(mplsLdpCsnTlv_t * csn, u_char * buff, int bufSize)
19292 + u_char *tempBuf = buff; /* no change for the buff ptr */
19294 + if (MPLS_CSNFIXLEN > bufSize) {
19295 + /* not enough data for csn data */
19296 + PRINT_ERR("failed decoding hello Csn\n");
19297 + return MPLS_DEC_BUFFTOOSMALL;
19300 + /*
19301 + * decode for the rest of the Csn
19302 + */
19303 + MEM_COPY(&(csn->seqNumber), tempBuf, MPLS_CSNFIXLEN);
19305 + csn->seqNumber = ntohl(csn->seqNumber);
19307 + return MPLS_CSNFIXLEN;
19309 +} /* End: Mpls_decodeLdpCsn */
19311 +/*
19312 + * Encode for Transport Address TLV
19313 + */
19316 + * encode
19317 + */
19318 +int Mpls_encodeLdpTrAdr(mplsLdpTrAdrTlv_t * trAdr, u_char * buff, int bufSize)
19320 + int encodedSize = 0;
19321 + u_char *tempBuf = buff; /* no change for the buff ptr */
19323 + if (MPLS_TRADRFIXLEN + MPLS_TLVFIXLEN > bufSize) {
19324 + /* not enough room */
19325 + return MPLS_ENC_BUFFTOOSMALL;
19328 + /*
19329 + * encode for tlv
19330 + */
19331 + encodedSize = Mpls_encodeLdpTlv(&(trAdr->baseTlv), tempBuf, bufSize);
19332 + if (encodedSize < 0) {
19333 + PRINT_ERR("failed encoding the tlv in hello TrAdr\n");
19334 + return MPLS_ENC_TLVERROR;
19336 + tempBuf += encodedSize;
19338 + trAdr->address = htonl(trAdr->address);
19340 + MEM_COPY(tempBuf, (u_char *) & (trAdr->address), MPLS_TRADRFIXLEN);
19342 + return (MPLS_TRADRFIXLEN + MPLS_TLVFIXLEN);
19344 +} /* End: Mpls_encodeLdpTrAdr */
19346 +/*
19347 + * decode
19348 + */
19349 +int Mpls_decodeLdpTrAdr(mplsLdpTrAdrTlv_t * trAdr, u_char * buff, int bufSize)
19351 + u_char *tempBuf = buff; /* no change for the buff ptr */
19353 + if (MPLS_TRADRFIXLEN > bufSize) {
19354 + /* not enough data for csn data */
19355 + PRINT_ERR("failed decoding hello TrAdr\n");
19356 + return MPLS_DEC_BUFFTOOSMALL;
19359 + /*
19360 + * decode for the rest of the TrAdr
19361 + */
19362 + MEM_COPY(&(trAdr->address), tempBuf, MPLS_TRADRFIXLEN);
19364 + trAdr->address = ntohl(trAdr->address);
19366 + return MPLS_TRADRFIXLEN;
19368 +} /* End: Mpls_decodeLdpTrAdr */
19370 +/*
19371 + * Encode for KeepAlive Message
19372 + */
19375 + * encode
19376 + */
19377 +int Mpls_encodeLdpKeepAliveMsg
19378 + (mplsLdpKeepAlMsg_t * keepAlive, u_char * buff, int bufSize) {
19379 + mplsLdpKeepAlMsg_t keepAliveCopy;
19380 + int encodedSize = 0;
19382 + if (MPLS_MSGIDFIXLEN + MPLS_TLVFIXLEN > bufSize) {
19383 + PRINT_ERR("failed to encode the keep alive msg: BUFFER TOO SMALL\n");
19384 + return MPLS_ENC_BUFFTOOSMALL;
19387 + keepAliveCopy = *keepAlive;
19389 + encodedSize = Mpls_encodeLdpBaseMsg(&(keepAliveCopy.baseMsg), buff, bufSize);
19390 + if (encodedSize < 0) {
19391 + return MPLS_ENC_BASEMSGERROR;
19393 + PRINT_OUT("Encode BaseMsg for keep alive on %d bytes\n", encodedSize);
19395 + return (MPLS_MSGIDFIXLEN + MPLS_TLVFIXLEN);
19397 +} /* End: Mpls_encodeLdpKeepAliveMsg */
19400 + * decode
19401 + */
19402 +int Mpls_decodeLdpKeepAliveMsg
19403 + (mplsLdpKeepAlMsg_t * keepAlive, u_char * buff, int bufSize) {
19404 + int decodedSize = 0;
19406 + memset(keepAlive, 0, MPLS_MSGIDFIXLEN + MPLS_TLVFIXLEN);
19407 + decodedSize = Mpls_decodeLdpBaseMsg(&(keepAlive->baseMsg), buff, bufSize);
19408 + if (decodedSize < 0) {
19409 + return MPLS_DEC_BASEMSGERROR;
19411 + PRINT_OUT("Decode BaseMsg for keep alive on %d bytes\n", decodedSize);
19413 + if (keepAlive->baseMsg.flags.flags.msgType != MPLS_KEEPAL_MSGTYPE) {
19414 + PRINT_ERR("Not the right message type; expected keep alive and got %x\n",
19415 + keepAlive->baseMsg.flags.flags.msgType);
19416 + return MPLS_MSGTYPEERROR;
19419 + return (MPLS_MSGIDFIXLEN + MPLS_TLVFIXLEN);
19421 +} /* End: Mpls_decodeLdpKeepAliveMsg */
19423 +/*
19424 + * Encode for Address List TLV
19425 + */
19428 + * encode
19429 + */
19430 +int Mpls_encodeLdpAdrTlv(mplsLdpAdrTlv_t * adrList, u_char * buff, int bufSize)
19432 + int i, numberAdr;
19433 + int encodedSize = 0;
19434 + u_char *tempBuf = buff; /* no change for the buff ptr */
19435 + u_short tempLength; /* to store the tlv length for
19437 + later use */
19439 + if (MPLS_TLVFIXLEN + (int)(adrList->baseTlv.length) > bufSize) {
19440 + /* not enough room */
19441 + return MPLS_ENC_BUFFTOOSMALL;
19444 + tempLength = adrList->baseTlv.length;
19445 + /*
19446 + * encode for tlv
19447 + */
19448 + encodedSize = Mpls_encodeLdpTlv(&(adrList->baseTlv), tempBuf, bufSize);
19449 + if (encodedSize < 0) {
19450 + PRINT_ERR("failed encoding the tlv in AdrList\n");
19451 + return MPLS_ENC_TLVERROR;
19454 + tempBuf += encodedSize;
19456 + adrList->addrFamily = htons(adrList->addrFamily);
19458 + numberAdr = (tempLength - sizeof(u_short)) / sizeof(u_int);
19459 + for (i = 0; i < numberAdr; i++) {
19460 + adrList->address[i] = htonl(adrList->address[i]);
19463 + MEM_COPY(tempBuf, (u_char *) & adrList->addrFamily, sizeof(u_short));
19465 + tempBuf += sizeof(u_short);
19467 + MEM_COPY(tempBuf,
19468 + (u_char *) & adrList->address, tempLength - sizeof(u_short));
19470 + return (tempLength + MPLS_TLVFIXLEN);
19472 +} /* End: Mpls_encodeLdpAdrTlv */
19475 + * decode
19477 + * Note: the tlvLength is used to specify what is the length of the
19478 + * encoding in the AdrTlv.
19479 + */
19480 +int Mpls_decodeLdpAdrTlv
19481 + (mplsLdpAdrTlv_t * adrList, u_char * buff, int bufSize, u_short tlvLength) {
19482 + u_char *tempBuf = buff; /* no change for the buff ptr */
19483 + int i, numberAdr;
19485 + if ((int)tlvLength > bufSize) {
19486 + /* not enough data for Adr list tlv */
19487 + PRINT_ERR("failed decoding AddrList tlv\n");
19488 + return MPLS_DEC_BUFFTOOSMALL;
19491 + /*
19492 + * decode for the addressFamily and addresses of the address list
19493 + */
19494 + MEM_COPY((u_char *) & adrList->addrFamily, tempBuf, sizeof(u_short));
19495 + tempBuf += sizeof(u_short);
19497 + adrList->addrFamily = ntohs(adrList->addrFamily);
19499 + MEM_COPY((u_char *) & adrList->address, tempBuf, tlvLength - sizeof(u_short));
19501 + numberAdr = (tlvLength - sizeof(u_short)) / sizeof(u_int);
19502 + for (i = 0; i < numberAdr; i++) {
19503 + adrList->address[i] = ntohl(adrList->address[i]);
19506 + return tlvLength;
19508 +} /* End: Mpls_decodeLdpAdrTlv */
19510 +/*
19511 + * Encode for Address / Address Withdraw messages
19512 + */
19515 + * encode
19516 + */
19517 +int Mpls_encodeLdpAdrMsg(mplsLdpAdrMsg_t * addrMsg, u_char * buff, int bufSize)
19519 + mplsLdpAdrMsg_t addrMsgCopy;
19520 + int encodedSize = 0;
19521 + u_int totalSize = 0;
19522 + u_char *tempBuf = buff; /* no change for the buff ptr */
19524 + /* check the length of the messageId + param */
19525 + if ((int)(addrMsg->baseMsg.msgLength) + MPLS_TLVFIXLEN > bufSize) {
19526 + PRINT_ERR("failed to encode the address msg: BUFFER TOO SMALL\n");
19527 + return MPLS_ENC_BUFFTOOSMALL;
19530 + addrMsgCopy = *addrMsg;
19532 + /*
19533 + * encode the base part of the pdu message
19534 + */
19535 + encodedSize = Mpls_encodeLdpBaseMsg(&(addrMsgCopy.baseMsg), tempBuf, bufSize);
19536 + if (encodedSize < 0) {
19537 + return MPLS_ENC_BASEMSGERROR;
19539 + PRINT_OUT("Encode BaseMsg for address on %d bytes\n", encodedSize);
19540 + tempBuf += encodedSize;
19541 + totalSize += encodedSize;
19543 + /*
19544 + * encode the address list tlv if any
19545 + */
19546 + if (addrMsg->adrListTlvExists) {
19547 + encodedSize = Mpls_encodeLdpAdrTlv(&(addrMsgCopy.addressList),
19548 + tempBuf, bufSize - totalSize);
19549 + if (encodedSize < 0) {
19550 + return MPLS_ENC_ADRLISTERROR;
19552 + PRINT_OUT("Encoded for AddressList Tlv %d bytes\n", encodedSize);
19555 + return (addrMsg->baseMsg.msgLength + MPLS_TLVFIXLEN);
19557 +} /* End: */
19560 + * decode
19561 + */
19562 +int Mpls_decodeLdpAdrMsg(mplsLdpAdrMsg_t * addrMsg, u_char * buff, int bufSize)
19564 + int decodedSize = 0;
19565 + u_int totalSize = 0;
19566 + u_int stopLength = 0;
19567 + u_int totalSizeParam = 0;
19568 + u_char *tempBuf = buff; /* no change for the buff ptr */
19569 + mplsLdpTlv_t tlvTemp;
19571 + /*
19572 + * decode the base part of the pdu message
19573 + */
19574 + memset(addrMsg, 0, sizeof(mplsLdpAdrMsg_t));
19575 + decodedSize = Mpls_decodeLdpBaseMsg(&(addrMsg->baseMsg), tempBuf, bufSize);
19576 + if (decodedSize < 0) {
19577 + return MPLS_DEC_BASEMSGERROR;
19579 + PRINT_OUT("Decode BaseMsg for address msg on %d bytes\n", decodedSize);
19581 + if ((addrMsg->baseMsg.flags.flags.msgType != MPLS_ADDR_MSGTYPE) &&
19582 + (addrMsg->baseMsg.flags.flags.msgType != MPLS_ADDRWITH_MSGTYPE)) {
19583 + PRINT_ERR("Not the right message type; expected adr and got %x\n",
19584 + addrMsg->baseMsg.flags.flags.msgType);
19585 + return MPLS_MSGTYPEERROR;
19588 + tempBuf += decodedSize;
19589 + totalSize += decodedSize;
19591 + if (bufSize - totalSize <= 0) {
19592 + /* nothing left for decoding */
19593 + PRINT_ERR("Adr msg does not have anything beside base msg\n");
19594 + return totalSize;
19597 + PRINT_OUT("bufSize = %d, totalSize = %d, addrMsg->baseMsg.msgLength = %d\n",
19598 + bufSize, totalSize, addrMsg->baseMsg.msgLength);
19600 + /* Have to check the baseMsg.msgLength to know when to finish.
19601 + * We finsh when the totalSizeParam is >= to the base message length - the
19602 + * message id length (4)
19603 + */
19605 + stopLength = addrMsg->baseMsg.msgLength - MPLS_MSGIDFIXLEN;
19606 + while (stopLength > totalSizeParam) {
19607 + /*
19608 + * decode the tlv to check what's next
19609 + */
19610 + memset(&tlvTemp, 0, MPLS_TLVFIXLEN);
19611 + decodedSize = Mpls_decodeLdpTlv(&tlvTemp, tempBuf, bufSize - totalSize);
19612 + if (decodedSize < 0) {
19613 + /* something wrong */
19614 + PRINT_ERR("ADR msg decode failed for tlv\n");
19615 + return MPLS_DEC_TLVERROR;
19618 + tempBuf += decodedSize;
19619 + totalSize += decodedSize;
19620 + totalSizeParam += decodedSize;
19622 + switch (tlvTemp.flags.flags.tBit) {
19623 + case MPLS_ADDRLIST_TLVTYPE:
19625 + decodedSize = Mpls_decodeLdpAdrTlv(&(addrMsg->addressList),
19626 + tempBuf, bufSize - totalSize, tlvTemp.length);
19627 + if (decodedSize < 0) {
19628 + PRINT_ERR("Failure when decoding AdrList tlv from adr msg\n");
19629 + return MPLS_DEC_ADRLISTERROR;
19631 + PRINT_OUT("Decoded for ADRLIST %d bytes\n", decodedSize);
19632 + tempBuf += decodedSize;
19633 + totalSize += decodedSize;
19634 + totalSizeParam += decodedSize;
19636 + addrMsg->adrListTlvExists = 1;
19637 + addrMsg->addressList.baseTlv = tlvTemp;
19638 + break;
19640 + default:
19642 + PRINT_ERR("Found wrong tlv type while decoding adr msg (%x)\n",
19643 + tlvTemp.flags.flags.tBit);
19644 + if (tlvTemp.flags.flags.uBit == 1) {
19645 + /* ignore the Tlv and continue processing */
19646 + tempBuf += tlvTemp.length;
19647 + totalSize += tlvTemp.length;
19648 + totalSizeParam += tlvTemp.length;
19649 + break;
19650 + } else {
19651 + /* drop the message; return error */
19652 + return MPLS_TLVTYPEERROR;
19655 + } /* switch type */
19657 + } /* while */
19659 + PRINT_OUT("totalsize for Mpls_decodeLdpAdrMsg is %d\n", totalSize);
19661 + return totalSize;
19663 +} /* End: Mpls_decodeLdpAdrMsg */
19665 +/*
19666 + * Encode for FEC ELEMENT
19667 + */
19670 + * encode
19671 + */
19672 +int Mpls_encodeLdpFecAdrEl
19673 + (mplsFecElement_t * fecAdrEl, u_char * buff, int bufSize, u_char type) {
19674 + int encodedSize = 0;
19675 + u_char *tempBuf = buff;
19677 + switch (type) {
19678 + case MPLS_WC_FEC:
19680 + if (MPLS_FEC_ELEMTYPELEN > bufSize) {
19681 + return MPLS_ENC_BUFFTOOSMALL;
19683 + *buff = fecAdrEl->wildcardEl.type;
19684 + encodedSize = MPLS_FEC_ELEMTYPELEN;
19685 + break;
19687 + case MPLS_PREFIX_FEC:
19689 + int preLenOctets;
19691 + fecAdrEl->addressEl.addressFam = htons(fecAdrEl->addressEl.addressFam);
19692 + fecAdrEl->addressEl.address = htonl(fecAdrEl->addressEl.address);
19693 + preLenOctets = (int)(fecAdrEl->addressEl.preLen / 8) +
19694 + ((int)(fecAdrEl->addressEl.preLen % 8) > 0 ? 1 : 0);
19696 + encodedSize = MPLS_FEC_ADRFAMLEN + MPLS_FEC_ELEMTYPELEN +
19697 + MPLS_FEC_PRELENLEN + preLenOctets;
19699 + if (encodedSize > bufSize) {
19700 + return MPLS_ENC_BUFFTOOSMALL;
19702 + *tempBuf = fecAdrEl->addressEl.type;
19703 + tempBuf++; /* for MPLS_FEC_ELEMTYPELEN */
19705 + MEM_COPY(tempBuf,
19706 + (u_char *) & (fecAdrEl->addressEl.addressFam), MPLS_FEC_ADRFAMLEN);
19707 + tempBuf += MPLS_FEC_ADRFAMLEN;
19709 + *tempBuf = fecAdrEl->addressEl.preLen;
19710 + tempBuf++; /* for MPLS_FEC_PRELENLEN */
19712 + MEM_COPY(tempBuf, (u_char *) & (fecAdrEl->addressEl.address),
19713 + preLenOctets);
19714 + break;
19716 + case MPLS_HOSTADR_FEC:
19718 + fecAdrEl->addressEl.addressFam = htons(fecAdrEl->addressEl.addressFam);
19719 + fecAdrEl->addressEl.address = htonl(fecAdrEl->addressEl.address);
19721 + encodedSize = MPLS_FEC_ADRFAMLEN + MPLS_FEC_ELEMTYPELEN +
19722 + MPLS_FEC_PRELENLEN + fecAdrEl->addressEl.preLen;
19724 + if (encodedSize > bufSize) {
19725 + return MPLS_ENC_BUFFTOOSMALL;
19727 + *tempBuf = fecAdrEl->addressEl.type;
19728 + tempBuf++; /* for MPLS_FEC_ELEMTYPELEN */
19730 + MEM_COPY(tempBuf,
19731 + (u_char *) & (fecAdrEl->addressEl.addressFam), MPLS_FEC_ADRFAMLEN);
19732 + tempBuf += MPLS_FEC_ADRFAMLEN;
19734 + *tempBuf = fecAdrEl->addressEl.preLen;
19735 + tempBuf++; /* for MPLS_FEC_PRELENLEN */
19737 + MEM_COPY(tempBuf,
19738 + (u_char *) & (fecAdrEl->addressEl.address),
19739 + fecAdrEl->addressEl.preLen);
19740 + break;
19742 + case MPLS_CRLSP_FEC:
19744 + if (MPLS_FEC_CRLSPLEN > bufSize) {
19745 + return MPLS_ENC_BUFFTOOSMALL;
19747 + fecAdrEl->crlspEl.res1 = 0;
19748 + fecAdrEl->crlspEl.res2 = 0;
19749 + MEM_COPY(tempBuf, (u_char *) & (fecAdrEl->crlspEl), MPLS_FEC_CRLSPLEN);
19750 + encodedSize = MPLS_FEC_CRLSPLEN;
19751 + break;
19753 + default:
19755 + PRINT_ERR("Found wrong FEC type while encoding FEC elem (%d)\n", type);
19756 + return MPLS_ENC_FECELEMERROR;
19757 + break;
19759 + } /* end: switch */
19761 + return encodedSize;
19763 +} /* End: Mpls_encodeLdpFecAdrEl */
19766 + * decode
19767 + */
19768 +int Mpls_decodeLdpFecAdrEl
19769 + (mplsFecElement_t * fecAdrEl, u_char * buff, int bufSize, u_char type) {
19770 + int decodedSize = 0;
19771 + u_char *tempBuff = buff;
19772 + u_int preLen = 0;
19774 + switch (type) {
19775 + case MPLS_WC_FEC:
19777 + fecAdrEl->wildcardEl.type = *buff;
19778 + decodedSize = MPLS_FEC_ELEMTYPELEN;
19779 + break;
19781 + case MPLS_PREFIX_FEC:
19783 + decodedSize = MPLS_FEC_ADRFAMLEN + MPLS_FEC_ELEMTYPELEN +
19784 + MPLS_FEC_PRELENLEN;
19785 + if (decodedSize > bufSize) {
19786 + return MPLS_DEC_BUFFTOOSMALL;
19788 + fecAdrEl->addressEl.type = *tempBuff;
19789 + tempBuff++; /* for MPLS_FEC_ELEMTYPELEN */
19791 + MEM_COPY((u_char *) & (fecAdrEl->addressEl.addressFam),
19792 + tempBuff, MPLS_FEC_ADRFAMLEN);
19793 + tempBuff += MPLS_FEC_ADRFAMLEN;
19795 + fecAdrEl->addressEl.preLen = *tempBuff;
19796 + tempBuff++; /* for MPLS_FEC_PRELENLEN */
19798 + fecAdrEl->addressEl.addressFam = ntohs(fecAdrEl->addressEl.addressFam);
19800 + /* now we get the prefix; we need to use the preLen which was
19801 + decoded from buff */
19803 + preLen = (int)(fecAdrEl->addressEl.preLen / 8) +
19804 + ((int)(fecAdrEl->addressEl.preLen % 8) > 0 ? 1 : 0);
19806 + if (fecAdrEl->addressEl.preLen > sizeof(u_int) * 8) {
19807 + /* error - the length cannot exeed 32 bits */
19808 + /* skip the FEC and return error code */
19809 + /* fill in the preLen field to the number of bytes for this
19810 + fec; we need it to know how much to skip from the buffer
19811 + when we do the decoding for the following fec element */
19812 + fecAdrEl->addressEl.preLen = preLen + decodedSize;
19813 + return MPLS_FECERROR;
19815 + if ((int)preLen > bufSize - decodedSize) {
19816 + return MPLS_DEC_BUFFTOOSMALL;
19818 + MEM_COPY((u_char *) & (fecAdrEl->addressEl.address), tempBuff, preLen);
19820 + fecAdrEl->addressEl.address = ntohl(fecAdrEl->addressEl.address);
19821 + decodedSize += preLen;
19822 + break;
19824 + case MPLS_HOSTADR_FEC:
19826 + decodedSize = MPLS_FEC_ADRFAMLEN + MPLS_FEC_ELEMTYPELEN +
19827 + MPLS_FEC_PRELENLEN;
19828 + if (decodedSize > bufSize) {
19829 + return MPLS_DEC_BUFFTOOSMALL;
19831 + fecAdrEl->addressEl.type = *tempBuff;
19832 + tempBuff++; /* for MPLS_FEC_ELEMTYPELEN */
19834 + MEM_COPY((u_char *) & (fecAdrEl->addressEl.addressFam),
19835 + tempBuff, MPLS_FEC_ADRFAMLEN);
19836 + tempBuff += MPLS_FEC_ADRFAMLEN;
19838 + fecAdrEl->addressEl.preLen = *tempBuff;
19839 + tempBuff++; /* for MPLS_FEC_PRELENLEN */
19841 + fecAdrEl->addressEl.addressFam = ntohs(fecAdrEl->addressEl.addressFam);
19843 + /* now we get the host address; we need to use the preLen which was
19844 + decoded from buff */
19846 + preLen = fecAdrEl->addressEl.preLen;
19847 + if (fecAdrEl->addressEl.preLen > sizeof(u_int)) {
19848 + /* error - the length cannot exeed 32 bits */
19849 + /* skip the FEC and return error code */
19850 + /* fill in the preLen field to the number of bytes for this
19851 + fec; we need it to know how much to skip from the buffer
19852 + when we do the decoding for the following fec element */
19853 + fecAdrEl->addressEl.preLen = preLen + decodedSize;
19854 + return MPLS_FECERROR;
19856 + if ((int)preLen > bufSize - decodedSize) {
19857 + return MPLS_DEC_BUFFTOOSMALL;
19859 + MEM_COPY((u_char *) & (fecAdrEl->addressEl.address), tempBuff, preLen);
19861 + fecAdrEl->addressEl.address = ntohl(fecAdrEl->addressEl.address);
19862 + decodedSize += preLen;
19863 + break;
19865 + case MPLS_CRLSP_FEC:
19867 + if (MPLS_FEC_CRLSPLEN > bufSize) {
19868 + return MPLS_DEC_BUFFTOOSMALL;
19870 + MEM_COPY((u_char *) & (fecAdrEl->crlspEl), tempBuff, MPLS_FEC_CRLSPLEN);
19871 + decodedSize = MPLS_FEC_CRLSPLEN;
19872 + break;
19874 + default:
19876 + PRINT_ERR("Found wrong FEC type while decoding FEC elem (%d)\n", type);
19877 + return MPLS_DEC_FECELEMERROR;
19878 + break;
19880 + } /* end: switch */
19882 + return decodedSize;
19884 +} /* End: Mpls_decodeLdpFecAdrEl */
19886 +/*
19887 + * Encode for FEC TLV
19888 + */
19891 + * encode
19892 + */
19893 +int Mpls_encodeLdpFecTlv(mplsLdpFecTlv_t * fecTlv, u_char * buff, int bufSize)
19895 + u_char *tempBuf = buff; /* no change for the buff ptr */
19896 + u_short i;
19897 + int encodedSize = 0;
19898 + u_int fecElSize = 0; /* used to compute the sum of
19900 + all fec elements */
19902 + if ((int)fecTlv->baseTlv.length + MPLS_TLVFIXLEN > bufSize) {
19903 + /* not enough room */
19904 + return MPLS_ENC_BUFFTOOSMALL;
19907 + /* check how many fec elements we have */
19908 + if (fecTlv->numberFecElements > MPLS_MAXNUMFECELEMENT) {
19909 + /* too many fec elem; need to increase MPLS_MAXNUMFECELEMENT */
19910 + PRINT_ERR("Too many fec elem\n");
19911 + return MPLS_FECTLVERROR;
19914 + for (i = 0; i < fecTlv->numberFecElements; i++) {
19915 + if ((fecTlv->fecElemTypes[i] == MPLS_WC_FEC) &&
19916 + (fecTlv->numberFecElements != 1)) {
19917 + return MPLS_WC_FECERROR;
19921 + /*
19922 + * encode for tlv
19923 + */
19924 + encodedSize = Mpls_encodeLdpTlv(&(fecTlv->baseTlv), tempBuf, bufSize);
19925 + if (encodedSize < 0) {
19926 + PRINT_ERR("failed encoding the tlv in FEC tlv\n");
19927 + return MPLS_ENC_TLVERROR;
19929 + tempBuf += encodedSize;
19930 + fecElSize += encodedSize;
19932 + /* encode now the FEC elements; check if wc exists; if it is there
19933 + then it should be the only element */
19935 + for (i = 0; i < fecTlv->numberFecElements; i++) {
19936 + encodedSize = Mpls_encodeLdpFecAdrEl(&(fecTlv->fecElArray[i]),
19937 + tempBuf, bufSize - fecElSize, fecTlv->fecElemTypes[i]);
19938 + if (encodedSize < 0) {
19939 + return MPLS_ENC_FECELEMERROR;
19941 + tempBuf += encodedSize;
19942 + fecElSize += encodedSize;
19945 + return fecElSize;
19947 +} /* End: Mpls_encodeLdpFecTlv */
19950 + * decode
19951 + */
19952 +int Mpls_decodeLdpFecTlv
19953 + (mplsLdpFecTlv_t * fecTlv, u_char * buff, int bufSize, u_short tlvLength) {
19954 + u_char *tempBuf = buff; /* no change for the buff ptr */
19955 + int decodedSize = 0;
19956 + u_int fecElSize = 0; /* used to compute the sum of
19958 + all fec elements */
19959 + u_short i = 0;
19960 + u_char type;
19962 + if ((int)tlvLength > bufSize) {
19963 + /* not enough data for Fec elements tlv */
19964 + PRINT_ERR("failed decoding FEC elements tlv\n");
19965 + return MPLS_DEC_BUFFTOOSMALL;
19968 + /*
19969 + * decode for the FEC elements; check also that if we have a wc element,
19970 + * it is the only element encoded in the FEC;
19971 + */
19972 + type = *tempBuf; /* first thing after the TLV base should be the type
19973 + of the fec element */
19975 + fecTlv->numberFecElements = 0;
19977 + while (tlvLength > fecElSize) {
19979 + /* check how many fec elements we have */
19980 + if (fecTlv->numberFecElements > (u_short) (MPLS_MAXNUMFECELEMENT - 1)) {
19981 + /* too many fec elem; need to increase MPLS_MAXNUMFECELEMENT */
19982 + PRINT_ERR("Too many fec elem\n");
19983 + return MPLS_FECTLVERROR;
19986 + decodedSize = Mpls_decodeLdpFecAdrEl(&(fecTlv->fecElArray[i]),
19987 + tempBuf, bufSize - fecElSize, type);
19988 + if ((decodedSize < 0) && (decodedSize != MPLS_FECERROR)) {
19989 + return MPLS_DEC_FECELEMERROR;
19990 + } else {
19991 + /* if the element had wrong preLen value, just skip it */
19992 + if (decodedSize != MPLS_FECERROR) {
19993 + fecTlv->fecElemTypes[i] = type;
19994 + fecTlv->numberFecElements++;
19995 + i++;
19997 + tempBuf += decodedSize;
19998 + fecElSize += decodedSize;
19999 + } else {
20000 + /* the preLen was filled with the total length
20001 + of the fec element to be skipped */
20002 + tempBuf += fecTlv->fecElArray[i].addressEl.preLen;
20003 + fecElSize += fecTlv->fecElArray[i].addressEl.preLen;
20007 + /* get the type of the next element */
20008 + type = *tempBuf;
20010 + } /* end while */
20012 + for (i = 0; i < fecTlv->numberFecElements; i++) {
20013 + if ((fecTlv->fecElemTypes[i] == MPLS_WC_FEC) &&
20014 + (fecTlv->numberFecElements != 1)) {
20015 + return MPLS_WC_FECERROR;
20019 + return fecElSize; /* fecElSize should be equal to tlvLength */
20021 +} /* End: Mpls_decodeLdpFecTlv */
20023 +/*
20024 + * Encode for Generic label TLV
20025 + */
20028 + * encode
20029 + */
20030 +int Mpls_encodeLdpGenLblTlv
20031 + (mplsLdpGenLblTlv_t * genLbl, u_char * buff, int bufSize) {
20032 + int encodedSize = 0;
20033 + u_char *tempBuf = buff; /* no change for the buff ptr */
20035 + if (MPLS_TLVFIXLEN + (int)(genLbl->baseTlv.length) > bufSize) {
20036 + /* not enough room */
20037 + return MPLS_ENC_BUFFTOOSMALL;
20040 + /*
20041 + * encode for tlv
20042 + */
20043 + encodedSize = Mpls_encodeLdpTlv(&(genLbl->baseTlv), tempBuf, bufSize);
20044 + if (encodedSize < 0) {
20045 + PRINT_ERR("failed encoding the tlv in Generic Label\n");
20046 + return MPLS_ENC_TLVERROR;
20048 + tempBuf += encodedSize;
20050 + genLbl->label = htonl(genLbl->label);
20052 + MEM_COPY(tempBuf, (u_char *) & (genLbl->label), MPLS_LBLFIXLEN);
20054 + return (MPLS_TLVFIXLEN + MPLS_LBLFIXLEN);
20056 +} /* End: Mpls_encodeLdpGenLblTlv */
20059 + * decode
20060 + */
20061 +int Mpls_decodeLdpGenLblTlv
20062 + (mplsLdpGenLblTlv_t * genLbl, u_char * buff, int bufSize) {
20063 + if (MPLS_LBLFIXLEN > bufSize) {
20064 + /* not enough data for generic label tlv */
20065 + PRINT_ERR("failed decoding Generic tlv\n");
20066 + return MPLS_DEC_BUFFTOOSMALL;
20069 + /*
20070 + * decode the label
20071 + */
20072 + MEM_COPY((u_char *) & (genLbl->label), buff, MPLS_LBLFIXLEN);
20074 + genLbl->label = ntohl(genLbl->label);
20076 + return MPLS_LBLFIXLEN;
20078 +} /* End: Mpls_decodeLdpGenLblTlv */
20080 +/*
20081 + * Encode for ATM Label TLV
20082 + */
20085 + * encode
20086 + */
20087 +int Mpls_encodeLdpAtmLblTlv
20088 + (mplsLdpAtmLblTlv_t * atmLblTlv, u_char * buff, int bufSize) {
20089 + int encodedSize = 0;
20090 + u_char *tempBuf = buff; /* no change for the buff ptr */
20091 + u_char *atmLblPtr;
20093 + if (MPLS_TLVFIXLEN + MPLS_LBLFIXLEN > bufSize) {
20094 + /* not enough room */
20095 + return MPLS_ENC_BUFFTOOSMALL;
20098 + atmLblPtr = (u_char *) atmLblTlv;
20100 + /*
20101 + * encode for tlv
20102 + */
20103 + encodedSize = Mpls_encodeLdpTlv(&(atmLblTlv->baseTlv),
20104 + tempBuf, MPLS_TLVFIXLEN);
20105 + if (encodedSize < 0) {
20106 + return MPLS_ENC_TLVERROR;
20108 + tempBuf += encodedSize;
20109 + atmLblPtr += encodedSize;
20111 + /*
20112 + * encode for flags
20113 + */
20114 + atmLblTlv->flags.flags.res = 0;
20115 + atmLblTlv->flags.mark = htons(atmLblTlv->flags.mark);
20116 + atmLblTlv->vci = htons(atmLblTlv->vci);
20118 + MEM_COPY(tempBuf, atmLblPtr, MPLS_LBLFIXLEN);
20120 + return (MPLS_LBLFIXLEN + MPLS_TLVFIXLEN);
20122 +} /* End: Mpls_encodeLdpAtmLblTlv */
20125 + * decode
20126 + */
20127 +int Mpls_decodeLdpAtmLblTlv
20128 + (mplsLdpAtmLblTlv_t * atmLblTlv, u_char * buff, int bufSize) {
20129 + u_char *atmLblTlvPtr;
20131 + if (MPLS_LBLFIXLEN > bufSize) {
20132 + /* not enough data for AtmLabel */
20133 + PRINT_ERR("failed decoding atm label tlv\n");
20134 + return MPLS_DEC_BUFFTOOSMALL;
20137 + atmLblTlvPtr = (u_char *) atmLblTlv;
20138 + atmLblTlvPtr += MPLS_TLVFIXLEN; /* to point after the Tlv which was
20139 + decoded before we reach here */
20140 + /*
20141 + * decode for the rest of the AtmLblTlv
20142 + */
20143 + MEM_COPY(atmLblTlvPtr, buff, MPLS_LBLFIXLEN);
20145 + atmLblTlv->flags.mark = ntohs(atmLblTlv->flags.mark);
20146 + atmLblTlv->vci = ntohs(atmLblTlv->vci);
20148 + return MPLS_LBLFIXLEN;
20150 +} /* End: Mpls_decodeLdpAtmLblTlv */
20152 +/*
20153 + * Encode for FR Label TLV
20154 + */
20157 + * encode
20158 + */
20159 +int Mpls_encodeLdpFrLblTlv
20160 + (mplsLdpFrLblTlv_t * frLblTlv, u_char * buff, int bufSize) {
20161 + int encodedSize = 0;
20162 + u_char *tempBuf = buff; /* no change for the buff ptr */
20164 + if (MPLS_TLVFIXLEN + MPLS_LBLFIXLEN > bufSize) {
20165 + /* not enough room */
20166 + return MPLS_ENC_BUFFTOOSMALL;
20169 + /*
20170 + * encode for tlv
20171 + */
20172 + encodedSize = Mpls_encodeLdpTlv(&(frLblTlv->baseTlv),
20173 + tempBuf, MPLS_TLVFIXLEN);
20174 + if (encodedSize < 0) {
20175 + return MPLS_ENC_TLVERROR;
20177 + tempBuf += encodedSize;
20179 + /*
20180 + * encode for flags
20181 + */
20182 + frLblTlv->flags.mark = htonl(frLblTlv->flags.mark);
20184 + MEM_COPY(tempBuf, (u_char *) & (frLblTlv->flags.mark), MPLS_LBLFIXLEN);
20186 + return (MPLS_LBLFIXLEN + MPLS_TLVFIXLEN);
20188 +} /* End: Mpls_encodeLdpFrLblTlv */
20191 + * decode
20192 + */
20193 +int Mpls_decodeLdpFrLblTlv
20194 + (mplsLdpFrLblTlv_t * frLblTlv, u_char * buff, int bufSize) {
20195 + u_char *tempBuf = buff; /* no change for the buff ptr */
20197 + if (MPLS_LBLFIXLEN > bufSize) {
20198 + /* not enough data for FrLabel */
20199 + PRINT_ERR("failed decoding fr label tlv\n");
20200 + return MPLS_DEC_BUFFTOOSMALL;
20203 + /*
20204 + * decode for the rest of the FrLblTlv
20205 + */
20206 + MEM_COPY((u_char *) & (frLblTlv->flags.mark), tempBuf, MPLS_LBLFIXLEN);
20208 + frLblTlv->flags.mark = ntohl(frLblTlv->flags.mark);
20210 + return MPLS_LBLFIXLEN;
20212 +} /* End: Mpls_decodeLdpFrLblTlv */
20214 +/*
20215 + * Encode for Hop Count TLV
20216 + */
20219 + * encode
20220 + */
20221 +int Mpls_encodeLdpHopTlv
20222 + (mplsLdpHopTlv_t * hopCountTlv, u_char * buff, int bufSize) {
20223 + int encodedSize = 0;
20224 + u_char *tempBuf = buff; /* no change for the buff ptr */
20226 + if (MPLS_TLVFIXLEN + MPLS_HOPCOUNTFIXLEN > bufSize) {
20227 + /* not enough room */
20228 + return MPLS_ENC_BUFFTOOSMALL;
20231 + /*
20232 + * encode for tlv
20233 + */
20234 + encodedSize = Mpls_encodeLdpTlv(&(hopCountTlv->baseTlv),
20235 + tempBuf, MPLS_TLVFIXLEN);
20236 + if (encodedSize < 0) {
20237 + return MPLS_ENC_TLVERROR;
20239 + tempBuf += encodedSize;
20241 + /*
20242 + * encode for hop count value
20243 + */
20244 + *tempBuf = hopCountTlv->hcValue;
20246 + return (MPLS_HOPCOUNTFIXLEN + MPLS_TLVFIXLEN);
20248 +} /* End: Mpls_encodeLdpFrLblTlv */
20251 + * decode
20252 + */
20253 +int Mpls_decodeLdpHopTlv
20254 + (mplsLdpHopTlv_t * hopCountTlv, u_char * buff, int bufSize) {
20255 + if (MPLS_HOPCOUNTFIXLEN > bufSize) {
20256 + /* not enough data for hop count value */
20257 + PRINT_ERR("failed decoding hop count tlv\n");
20258 + return MPLS_DEC_BUFFTOOSMALL;
20261 + /*
20262 + * decode for the hop count value
20263 + */
20264 + hopCountTlv->hcValue = *buff;
20266 + return MPLS_HOPCOUNTFIXLEN;
20268 +} /* End: Mpls_decodeLdpHopTlv */
20270 +/*
20271 + * Encode for Lbl Msg Id TLV
20272 + */
20275 + * encode
20276 + */
20277 +int Mpls_encodeLdpLblMsgIdTlv
20278 + (mplsLdpLblMsgIdTlv_t * lblMsgIdTlv, u_char * buff, int bufSize) {
20279 + int encodedSize = 0;
20280 + u_char *tempBuf = buff; /* no change for the buff ptr */
20282 + if (MPLS_TLVFIXLEN + MPLS_LBLFIXLEN > bufSize) {
20283 + /* not enough room */
20284 + return MPLS_ENC_BUFFTOOSMALL;
20287 + /*
20288 + * encode for tlv
20289 + */
20290 + encodedSize = Mpls_encodeLdpTlv(&(lblMsgIdTlv->baseTlv),
20291 + tempBuf, MPLS_TLVFIXLEN);
20292 + if (encodedSize < 0) {
20293 + return MPLS_ENC_TLVERROR;
20295 + tempBuf += encodedSize;
20297 + /*
20298 + * encode for msg id
20299 + */
20301 + lblMsgIdTlv->msgId = htonl(lblMsgIdTlv->msgId);
20303 + MEM_COPY(tempBuf, (u_char *) & (lblMsgIdTlv->msgId), MPLS_LBLFIXLEN);
20305 + return (MPLS_LBLFIXLEN + MPLS_TLVFIXLEN);
20307 +} /* End: Mpls_encodeLdpFrLblTlv */
20310 + * decode
20311 + */
20312 +int Mpls_decodeLdpLblMsgIdTlv
20313 + (mplsLdpLblMsgIdTlv_t * lblMsgIdTlv, u_char * buff, int bufSize) {
20314 + if (MPLS_LBLFIXLEN > bufSize) {
20315 + /* not enough data for msg id tlv */
20316 + PRINT_ERR("failed decoding lbl msg id tlv\n");
20317 + return MPLS_DEC_BUFFTOOSMALL;
20320 + /*
20321 + * decode for the rest of the LblMsgId Tlv
20322 + */
20323 + MEM_COPY((u_char *) & (lblMsgIdTlv->msgId), buff, MPLS_LBLFIXLEN);
20325 + lblMsgIdTlv->msgId = ntohl(lblMsgIdTlv->msgId);
20327 + return MPLS_LBLFIXLEN;
20329 +} /* End: Mpls_decodeLdpLblMsgIdTlv */
20331 +/*
20332 + * Encode for Path Vector TLV
20333 + */
20336 + * encode
20337 + */
20338 +int Mpls_encodeLdpPathVectorTlv
20339 + (mplsLdpPathTlv_t * pathVectorTlv, u_char * buff, int bufSize) {
20340 + u_char *pathVectorTlvPtr;
20341 + u_char *tempBuf = buff; /* no change for the buff ptr */
20342 + int encodedSize = 0;
20343 + u_int i, numLsrIds;
20344 + u_short tempLength; /* to store the tlv length for
20346 + later use */
20348 + if (MPLS_TLVFIXLEN + (int)(pathVectorTlv->baseTlv.length) > bufSize) {
20349 + /* not enough room */
20350 + return MPLS_ENC_BUFFTOOSMALL;
20353 + pathVectorTlvPtr = (u_char *) pathVectorTlv;
20354 + tempLength = pathVectorTlv->baseTlv.length;
20355 + /*
20356 + * encode for tlv
20357 + */
20358 + encodedSize = Mpls_encodeLdpTlv(&(pathVectorTlv->baseTlv),
20359 + tempBuf, MPLS_TLVFIXLEN);
20360 + if (encodedSize < 0) {
20361 + return MPLS_ENC_TLVERROR;
20363 + tempBuf += encodedSize;
20364 + pathVectorTlvPtr += encodedSize;
20366 + /*
20367 + * encode for labels
20368 + */
20370 + if (tempLength % MPLS_LBLFIXLEN != 0) {
20371 + return MPLS_PATHVECTORERROR;
20374 + numLsrIds = tempLength / MPLS_LBLFIXLEN;
20375 + if (numLsrIds > MPLS_MAXHOPSNUMBER) {
20376 + /* too many lsrIds; need to increase MPLS_MAXHOPSNUMBER */
20377 + PRINT_ERR("Too many lsr ids (%d)\n", numLsrIds);
20378 + return MPLS_PATHVECTORERROR;
20381 + for (i = 0; i < numLsrIds; i++) {
20382 + pathVectorTlv->lsrId[i] = htonl(pathVectorTlv->lsrId[i]);
20385 + MEM_COPY(tempBuf, pathVectorTlvPtr, tempLength);
20387 + return (tempLength + MPLS_TLVFIXLEN);
20389 +} /* End: Mpls_encodeLdpPathVectorTlv */
20392 + * decode
20393 + */
20394 +int Mpls_decodeLdpPathVectorTlv
20395 + (mplsLdpPathTlv_t * pathVectorTlv,
20396 + u_char * buff, int bufSize, u_short tlvLength) {
20397 + u_char *tempBuf = buff; /* no change for the buff ptr */
20398 + u_int i, numLsrIds;
20400 + if (MPLS_LBLFIXLEN > bufSize) {
20401 + /* not enough data for msg id tlv */
20402 + PRINT_ERR("failed decoding lbl msg id tlv\n");
20403 + return MPLS_DEC_BUFFTOOSMALL;
20406 + if (tlvLength % MPLS_LBLFIXLEN != 0) {
20407 + PRINT_ERR("Wrong length for Path vector tlv (%d)\n", tlvLength);
20408 + return MPLS_PATHVECTORERROR;
20411 + numLsrIds = tlvLength / MPLS_LBLFIXLEN;
20412 + if (numLsrIds > MPLS_MAXHOPSNUMBER) {
20413 + /* too many lsrIds; need to increase MPLS_MAXHOPSNUMBER */
20414 + PRINT_ERR("Too many lsr ids (%d)\n", numLsrIds);
20415 + return MPLS_PATHVECTORERROR;
20418 + /*
20419 + * decode for the rest of the LblMsgId Tlv
20420 + */
20421 + MEM_COPY((u_char *) (pathVectorTlv->lsrId), tempBuf, tlvLength);
20423 + for (i = 0; i < numLsrIds; i++) {
20424 + pathVectorTlv->lsrId[i] = ntohl(pathVectorTlv->lsrId[i]);
20427 + return tlvLength;
20429 +} /* End: Mpls_decodeLdpPathVectorTlv */
20431 +/*
20432 + * Encode for Label Mapping Message
20433 + */
20436 + * encode
20437 + */
20438 +int Mpls_encodeLdpLblMapMsg
20439 + (mplsLdpLblMapMsg_t * lblMapMsg, u_char * buff, int bufSize) {
20440 + mplsLdpLblMapMsg_t lblMapMsgCopy;
20441 + int encodedSize = 0;
20442 + u_int totalSize = 0;
20443 + u_char *tempBuf = buff; /* no change for the buff ptr */
20445 + /* check the length of the messageId + param */
20446 + if ((int)(lblMapMsg->baseMsg.msgLength) + MPLS_TLVFIXLEN > bufSize) {
20447 + PRINT_ERR("failed to encode the lbl mapping msg: BUFFER TOO SMALL\n");
20448 + return MPLS_ENC_BUFFTOOSMALL;
20451 + lblMapMsgCopy = *lblMapMsg;
20453 + /*
20454 + * encode the base part of the pdu message
20455 + */
20456 + encodedSize = Mpls_encodeLdpBaseMsg(&(lblMapMsgCopy.baseMsg),
20457 + tempBuf, bufSize);
20458 + if (encodedSize < 0) {
20459 + return MPLS_ENC_BASEMSGERROR;
20461 + PRINT_OUT("Encode BaseMsg for label mapping on %d bytes\n", encodedSize);
20462 + tempBuf += encodedSize;
20463 + totalSize += encodedSize;
20465 + /*
20466 + * encode the tlv if any
20467 + */
20468 + if (lblMapMsgCopy.fecTlvExists) {
20469 + encodedSize = Mpls_encodeLdpFecTlv(&(lblMapMsgCopy.fecTlv),
20470 + tempBuf, bufSize - totalSize);
20471 + if (encodedSize < 0) {
20472 + return MPLS_ENC_FECERROR;
20474 + PRINT_OUT("Encoded for FEC Tlv %d bytes\n", encodedSize);
20475 + tempBuf += encodedSize;
20476 + totalSize += encodedSize;
20479 + if (lblMapMsgCopy.genLblTlvExists) {
20480 + encodedSize = Mpls_encodeLdpGenLblTlv(&(lblMapMsgCopy.genLblTlv),
20481 + tempBuf, bufSize - totalSize);
20482 + if (encodedSize < 0) {
20483 + return MPLS_ENC_GENLBLERROR;
20485 + PRINT_OUT("Encoded for Generic Label Tlv %d bytes\n", encodedSize);
20486 + tempBuf += encodedSize;
20487 + totalSize += encodedSize;
20489 + if (lblMapMsgCopy.atmLblTlvExists) {
20490 + encodedSize = Mpls_encodeLdpAtmLblTlv(&(lblMapMsgCopy.atmLblTlv),
20491 + tempBuf, bufSize - totalSize);
20492 + if (encodedSize < 0) {
20493 + return MPLS_ENC_MAPATMERROR;
20495 + PRINT_OUT("Encoded for Atm Label Tlv %d bytes\n", encodedSize);
20496 + tempBuf += encodedSize;
20497 + totalSize += encodedSize;
20499 + if (lblMapMsgCopy.frLblTlvExists) {
20500 + encodedSize = Mpls_encodeLdpFrLblTlv(&(lblMapMsgCopy.frLblTlv),
20501 + tempBuf, bufSize - totalSize);
20502 + if (encodedSize < 0) {
20503 + return MPLS_ENC_FRLBLERROR;
20505 + PRINT_OUT("Encoded for Fr Label Tlv %d bytes\n", encodedSize);
20506 + tempBuf += encodedSize;
20507 + totalSize += encodedSize;
20509 + if (lblMapMsgCopy.hopCountTlvExists) {
20510 + encodedSize = Mpls_encodeLdpHopTlv(&(lblMapMsgCopy.hopCountTlv),
20511 + tempBuf, bufSize - totalSize);
20512 + if (encodedSize < 0) {
20513 + return MPLS_ENC_HOPCOUNTERROR;
20515 + PRINT_OUT("Encoded for Hop Count Tlv %d bytes\n", encodedSize);
20516 + tempBuf += encodedSize;
20517 + totalSize += encodedSize;
20519 + if (lblMapMsgCopy.pathVecTlvExists) {
20520 + encodedSize = Mpls_encodeLdpPathVectorTlv(&(lblMapMsgCopy.pathVecTlv),
20521 + tempBuf, bufSize - totalSize);
20522 + if (encodedSize < 0) {
20523 + return MPLS_ENC_PATHVECERROR;
20525 + PRINT_OUT("Encoded for Path Vector Tlv %d bytes\n", encodedSize);
20526 + tempBuf += encodedSize;
20527 + totalSize += encodedSize;
20529 + if (lblMapMsgCopy.lblMsgIdTlvExists) {
20530 + encodedSize = Mpls_encodeLdpLblMsgIdTlv(&(lblMapMsgCopy.lblMsgIdTlv),
20531 + tempBuf, bufSize - totalSize);
20532 + if (encodedSize < 0) {
20533 + return MPLS_ENC_LBLMSGIDERROR;
20535 + PRINT_OUT("Encoded for lbl request msg id Tlv %d bytes\n", encodedSize);
20536 + tempBuf += encodedSize;
20537 + totalSize += encodedSize;
20539 + if (lblMapMsgCopy.trafficTlvExists) {
20540 + encodedSize = Mpls_encodeLdpTrafficTlv(&(lblMapMsgCopy.trafficTlv),
20541 + tempBuf, bufSize - totalSize);
20542 + if (encodedSize < 0) {
20543 + return MPLS_ENC_TRAFFICERROR;
20545 + PRINT_OUT("Encoded for Traffic Tlv %d bytes\n", encodedSize);
20546 + tempBuf += encodedSize;
20547 + totalSize += encodedSize;
20549 + if (lblMapMsgCopy.lspidTlvExists) {
20550 + encodedSize = Mpls_encodeLdpLspIdTlv(&(lblMapMsgCopy.lspidTlv),
20551 + tempBuf, bufSize - totalSize);
20552 + if (encodedSize < 0) {
20553 + return MPLS_ENC_LSPIDERROR;
20555 + PRINT_OUT("Encoded for LSPID Tlv %d bytes\n", encodedSize);
20556 + tempBuf += encodedSize;
20557 + totalSize += encodedSize;
20560 + return totalSize;
20562 +} /* End: Mpls_encodeLdpLblMapMsg */
20565 + * decode
20566 + */
20567 +int Mpls_decodeLdpLblMapMsg
20568 + (mplsLdpLblMapMsg_t * lblMapMsg, u_char * buff, int bufSize) {
20569 + int decodedSize = 0;
20570 + u_int totalSize = 0;
20571 + u_int stopLength = 0;
20572 + u_int totalSizeParam = 0;
20573 + u_char *tempBuf = buff; /* no change for the buff ptr */
20574 + mplsLdpTlv_t tlvTemp;
20576 + /*
20577 + * decode the base part of the pdu message
20578 + */
20579 + memset(lblMapMsg, 0, sizeof(mplsLdpLblMapMsg_t));
20580 + decodedSize = Mpls_decodeLdpBaseMsg(&(lblMapMsg->baseMsg), tempBuf, bufSize);
20581 + if (decodedSize < 0) {
20582 + return MPLS_DEC_BASEMSGERROR;
20584 + PRINT_OUT("Decode BaseMsg for Lbl Mapping on %d bytes\n", decodedSize);
20586 + if (lblMapMsg->baseMsg.flags.flags.msgType != MPLS_LBLMAP_MSGTYPE) {
20587 + PRINT_ERR("Not the right message type; expected lbl map and got %x\n",
20588 + lblMapMsg->baseMsg.flags.flags.msgType);
20589 + return MPLS_MSGTYPEERROR;
20592 + tempBuf += decodedSize;
20593 + totalSize += decodedSize;
20595 + if (bufSize - totalSize <= 0) {
20596 + /* nothing left for decoding */
20597 + PRINT_ERR("Lbl Mapping msg does not have anything beside base msg\n");
20598 + return totalSize;
20601 + PRINT_OUT
20602 + ("bufSize = %d, totalSize = %d, lblMapMsg->baseMsg.msgLength = %d\n",
20603 + bufSize, totalSize, lblMapMsg->baseMsg.msgLength);
20605 + /* Have to check the baseMsg.msgLength to know when to finish.
20606 + * We finsh when the totalSizeParam is >= to the base message length - the
20607 + * message id length (4)
20608 + */
20610 + stopLength = lblMapMsg->baseMsg.msgLength - MPLS_MSGIDFIXLEN;
20611 + while (stopLength > totalSizeParam) {
20612 + /*
20613 + * decode the tlv to check what's next
20614 + */
20615 + memset(&tlvTemp, 0, MPLS_TLVFIXLEN);
20616 + decodedSize = Mpls_decodeLdpTlv(&tlvTemp, tempBuf, bufSize - totalSize);
20617 + if (decodedSize < 0) {
20618 + /* something wrong */
20619 + PRINT_ERR("Label Mapping msg decode failed for tlv\n");
20620 + return MPLS_DEC_TLVERROR;
20623 + tempBuf += decodedSize;
20624 + totalSize += decodedSize;
20625 + totalSizeParam += decodedSize;
20627 + switch (tlvTemp.flags.flags.tBit) {
20628 + case MPLS_FEC_TLVTYPE:
20630 + decodedSize = Mpls_decodeLdpFecTlv(&(lblMapMsg->fecTlv),
20631 + tempBuf, bufSize - totalSize, tlvTemp.length);
20632 + if (decodedSize < 0) {
20633 + PRINT_ERR("Failure when decoding FEC tlv from LblMap msg\n");
20634 + return MPLS_DEC_FECERROR;
20636 + PRINT_OUT("Decoded for FEC %d bytes\n", decodedSize);
20637 + tempBuf += decodedSize;
20638 + totalSize += decodedSize;
20639 + totalSizeParam += decodedSize;
20641 + lblMapMsg->fecTlvExists = 1;
20642 + lblMapMsg->fecTlv.baseTlv = tlvTemp;
20643 + break;
20645 + case MPLS_GENLBL_TLVTYPE:
20647 + decodedSize = Mpls_decodeLdpGenLblTlv(&(lblMapMsg->genLblTlv),
20648 + tempBuf, bufSize - totalSize);
20649 + if (decodedSize < 0) {
20650 + PRINT_ERR("Failure when dec GEN Lbl tlv from LblMap msg\n");
20651 + return MPLS_DEC_GENLBLERROR;
20653 + PRINT_OUT("Decoded for Gen Lbl %d bytes\n", decodedSize);
20654 + tempBuf += decodedSize;
20655 + totalSize += decodedSize;
20656 + totalSizeParam += decodedSize;
20658 + lblMapMsg->genLblTlvExists = 1;
20659 + lblMapMsg->genLblTlv.baseTlv = tlvTemp;
20660 + break;
20662 + case MPLS_ATMLBL_TLVTYPE:
20664 + decodedSize = Mpls_decodeLdpAtmLblTlv(&(lblMapMsg->atmLblTlv),
20665 + tempBuf, bufSize - totalSize);
20666 + if (decodedSize < 0) {
20667 + PRINT_ERR("Failure when dec ATM Lbl tlv from LblMap msg\n");
20668 + return MPLS_DEC_MAPATMERROR;
20670 + PRINT_OUT("Decoded for Atm Lbl %d bytes\n", decodedSize);
20671 + tempBuf += decodedSize;
20672 + totalSize += decodedSize;
20673 + totalSizeParam += decodedSize;
20675 + lblMapMsg->atmLblTlvExists = 1;
20676 + lblMapMsg->atmLblTlv.baseTlv = tlvTemp;
20677 + break;
20679 + case MPLS_FRLBL_TLVTYPE:
20681 + decodedSize = Mpls_decodeLdpFrLblTlv(&(lblMapMsg->frLblTlv),
20682 + tempBuf, bufSize - totalSize);
20683 + if (decodedSize < 0) {
20684 + PRINT_ERR("Failure when dec FR Lbl tlv from LblMap msg\n");
20685 + return MPLS_DEC_FRLBLERROR;
20687 + PRINT_OUT("Decoded for Fr Lbl %d bytes\n", decodedSize);
20688 + tempBuf += decodedSize;
20689 + totalSize += decodedSize;
20690 + totalSizeParam += decodedSize;
20692 + lblMapMsg->frLblTlvExists = 1;
20693 + lblMapMsg->frLblTlv.baseTlv = tlvTemp;
20694 + break;
20696 + case MPLS_HOPCOUNT_TLVTYPE:
20698 + decodedSize = Mpls_decodeLdpHopTlv(&(lblMapMsg->hopCountTlv),
20699 + tempBuf, bufSize - totalSize);
20700 + if (decodedSize < 0) {
20701 + PRINT_ERR("Failure when dec HopCount tlv from LblMap msg\n");
20702 + return MPLS_DEC_HOPCOUNTERROR;
20704 + PRINT_OUT("Decoded for HopCount %d bytes\n", decodedSize);
20705 + tempBuf += decodedSize;
20706 + totalSize += decodedSize;
20707 + totalSizeParam += decodedSize;
20709 + lblMapMsg->hopCountTlvExists = 1;
20710 + lblMapMsg->hopCountTlv.baseTlv = tlvTemp;
20711 + break;
20713 + case MPLS_PATH_TLVTYPE:
20715 + decodedSize = Mpls_decodeLdpPathVectorTlv(&(lblMapMsg->pathVecTlv),
20716 + tempBuf, bufSize - totalSize, tlvTemp.length);
20717 + if (decodedSize < 0) {
20718 + PRINT_ERR("Failure when dec Path Vec tlv from LblMap msg\n");
20719 + return MPLS_DEC_PATHVECERROR;
20721 + PRINT_OUT("Decoded for PATH VECTOR %d bytes\n", decodedSize);
20722 + tempBuf += decodedSize;
20723 + totalSize += decodedSize;
20724 + totalSizeParam += decodedSize;
20726 + lblMapMsg->pathVecTlvExists = 1;
20727 + lblMapMsg->pathVecTlv.baseTlv = tlvTemp;
20728 + break;
20730 + case MPLS_REQMSGID_TLVTYPE:
20732 + decodedSize = Mpls_decodeLdpLblMsgIdTlv(&(lblMapMsg->lblMsgIdTlv),
20733 + tempBuf, bufSize - totalSize);
20734 + if (decodedSize < 0) {
20735 + PRINT_ERR("Failure when dec LblMsgId tlv from LblMap msg\n");
20736 + return MPLS_DEC_LBLMSGIDERROR;
20738 + PRINT_OUT("Decoded for LblMsgId %d bytes\n", decodedSize);
20739 + tempBuf += decodedSize;
20740 + totalSize += decodedSize;
20741 + totalSizeParam += decodedSize;
20743 + lblMapMsg->lblMsgIdTlvExists = 1;
20744 + lblMapMsg->lblMsgIdTlv.baseTlv = tlvTemp;
20745 + break;
20747 + case MPLS_TRAFFIC_TLVTYPE:
20749 + decodedSize = Mpls_decodeLdpTrafficTlv(&(lblMapMsg->trafficTlv),
20750 + tempBuf, bufSize - totalSize, tlvTemp.length);
20751 + if (decodedSize < 0) {
20752 + PRINT_ERR("Failure when dec Traffic tlv from LblMap msg\n");
20753 + return MPLS_DEC_TRAFFICERROR;
20755 + PRINT_OUT("Decoded for Traffic %d bytes\n", decodedSize);
20756 + tempBuf += decodedSize;
20757 + totalSize += decodedSize;
20758 + totalSizeParam += decodedSize;
20760 + lblMapMsg->trafficTlvExists = 1;
20761 + lblMapMsg->trafficTlv.baseTlv = tlvTemp;
20762 + break;
20764 + case MPLS_LSPID_TLVTYPE:
20766 + decodedSize = Mpls_decodeLdpLspIdTlv(&(lblMapMsg->lspidTlv),
20767 + tempBuf, bufSize - totalSize);
20768 + if (decodedSize < 0) {
20769 + PRINT_ERR("Failure when dec LSPID tlv from LblMap msg\n");
20770 + return MPLS_DEC_LSPIDERROR;
20772 + PRINT_OUT("Decoded for lspid tlv %d bytes\n", decodedSize);
20773 + tempBuf += decodedSize;
20774 + totalSize += decodedSize;
20775 + totalSizeParam += decodedSize;
20777 + lblMapMsg->lspidTlvExists = 1;
20778 + lblMapMsg->lspidTlv.baseTlv = tlvTemp;
20779 + break;
20781 + default:
20783 + PRINT_ERR("Found wrong tlv type while decoding lbl map msg (%x)\n",
20784 + tlvTemp.flags.flags.tBit);
20785 + if (tlvTemp.flags.flags.uBit == 1) {
20786 + /* ignore the Tlv and continue processing */
20787 + tempBuf += tlvTemp.length;
20788 + totalSize += tlvTemp.length;
20789 + totalSizeParam += tlvTemp.length;
20790 + break;
20791 + } else {
20792 + /* drop the message; return error */
20793 + return MPLS_TLVTYPEERROR;
20796 + } /* switch type */
20798 + } /* while */
20800 + PRINT_OUT("totalsize for Mpls_decodeLdpLblMapMsg is %d\n", totalSize);
20802 + return totalSize;
20804 +} /* End: Mpls_decodeLdpLblMapMsg */
20806 +/*
20807 + * Encode for Retrun MessageId TLV
20808 + */
20811 + * encode
20812 + */
20813 +int Mpls_encodeLdpLblRetMsgIdTlv
20814 + (mplsLdpLblRetMsgIdTlv_t * lblMsgIdTlv, u_char * buff, int bufSize) {
20815 + /*
20816 + * encode for tlv
20817 + */
20818 + if (Mpls_encodeLdpTlv(&(lblMsgIdTlv->baseTlv), buff, MPLS_TLVFIXLEN) < 0) {
20819 + return MPLS_ENC_TLVERROR;
20822 + return MPLS_TLVFIXLEN;
20824 +} /* End: Mpls_encodeLdpLblRetMsgIdTlv */
20827 + * decode
20828 + */
20829 +int Mpls_decodeLdpLblRetMsgIdTlv
20830 + (mplsLdpLblRetMsgIdTlv_t * lblMsgIdTlv, u_char * buff, int bufSize) {
20831 + /* this function does not need to do anything */
20832 + return 0;
20833 +} /* End: Mpls_decodeLdpLblRetMsgIdTlv */
20835 +/*
20836 + * Encode for Label Request Message
20837 + */
20840 + * encode
20841 + */
20842 +int Mpls_encodeLdpLblReqMsg
20843 + (mplsLdpLblReqMsg_t * lblReqMsg, u_char * buff, int bufSize) {
20844 + mplsLdpLblReqMsg_t lblReqMsgCopy;
20845 + int encodedSize;
20846 + u_int totalSize = 0;
20847 + u_char *tempBuf = buff; /* no change for the buff ptr */
20849 + /* check the length of the messageId + param */
20850 + if ((int)(lblReqMsg->baseMsg.msgLength) + MPLS_TLVFIXLEN > bufSize) {
20851 + PRINT_ERR("failed to encode the lbl request msg: BUFFER TOO SMALL\n");
20852 + return MPLS_ENC_BUFFTOOSMALL;
20855 + lblReqMsgCopy = *lblReqMsg;
20857 + /*
20858 + * encode the base part of the pdu message
20859 + */
20860 + encodedSize = Mpls_encodeLdpBaseMsg(&(lblReqMsgCopy.baseMsg),
20861 + tempBuf, bufSize);
20862 + if (encodedSize < 0) {
20863 + return MPLS_ENC_BASEMSGERROR;
20865 + PRINT_OUT("Encode BaseMsg for label request on %d bytes\n", encodedSize);
20866 + tempBuf += encodedSize;
20867 + totalSize += encodedSize;
20869 + /*
20870 + * encode the tlv if any
20871 + */
20872 + if (lblReqMsgCopy.fecTlvExists) {
20873 + encodedSize = Mpls_encodeLdpFecTlv(&(lblReqMsgCopy.fecTlv),
20874 + tempBuf, bufSize - totalSize);
20875 + if (encodedSize < 0) {
20876 + return MPLS_ENC_FECERROR;
20878 + PRINT_OUT("Encoded for FEC Tlv %d bytes\n", encodedSize);
20879 + tempBuf += encodedSize;
20880 + totalSize += encodedSize;
20882 + if (lblReqMsgCopy.hopCountTlvExists) {
20883 + encodedSize = Mpls_encodeLdpHopTlv(&(lblReqMsgCopy.hopCountTlv),
20884 + tempBuf, bufSize - totalSize);
20885 + if (encodedSize < 0) {
20886 + return MPLS_ENC_HOPCOUNTERROR;
20888 + PRINT_OUT("Encoded for Hop Count Tlv %d bytes\n", encodedSize);
20889 + tempBuf += encodedSize;
20890 + totalSize += encodedSize;
20892 + if (lblReqMsgCopy.pathVecTlvExists) {
20893 + encodedSize = Mpls_encodeLdpPathVectorTlv(&(lblReqMsgCopy.pathVecTlv),
20894 + tempBuf, bufSize - totalSize);
20895 + if (encodedSize < 0) {
20896 + return MPLS_ENC_PATHVECERROR;
20898 + PRINT_OUT("Encoded for Hop Count Tlv %d bytes\n", encodedSize);
20899 + tempBuf += encodedSize;
20900 + totalSize += encodedSize;
20902 + if (lblReqMsgCopy.lblMsgIdTlvExists) {
20903 + encodedSize = Mpls_encodeLdpLblRetMsgIdTlv(&(lblReqMsgCopy.lblMsgIdTlv),
20904 + tempBuf, bufSize - totalSize);
20905 + if (encodedSize < 0) {
20906 + return MPLS_ENC_LBLMSGIDERROR;
20908 + PRINT_OUT("Encoded for Hop Count Tlv %d bytes\n", encodedSize);
20909 + tempBuf += encodedSize;
20910 + totalSize += encodedSize;
20912 + if (lblReqMsgCopy.erTlvExists) {
20913 + encodedSize = Mpls_encodeLdpERTlv(&(lblReqMsgCopy.erTlv),
20914 + tempBuf, bufSize - totalSize);
20915 + if (encodedSize < 0) {
20916 + return MPLS_ENC_ERTLVERROR;
20918 + PRINT_OUT("Encoded for CR Tlv %d bytes\n", encodedSize);
20919 + tempBuf += encodedSize;
20920 + totalSize += encodedSize;
20922 + if (lblReqMsgCopy.trafficTlvExists) {
20923 + encodedSize = Mpls_encodeLdpTrafficTlv(&(lblReqMsgCopy.trafficTlv),
20924 + tempBuf, bufSize - totalSize);
20925 + if (encodedSize < 0) {
20926 + return MPLS_ENC_TRAFFICERROR;
20928 + PRINT_OUT("Encoded for Traffic Tlv %d bytes\n", encodedSize);
20929 + tempBuf += encodedSize;
20930 + totalSize += encodedSize;
20932 + if (lblReqMsgCopy.lspidTlvExists) {
20933 + encodedSize = Mpls_encodeLdpLspIdTlv(&(lblReqMsgCopy.lspidTlv),
20934 + tempBuf, bufSize - totalSize);
20935 + if (encodedSize < 0) {
20936 + return MPLS_ENC_LSPIDERROR;
20938 + PRINT_OUT("Encoded for LSPID Tlv %d bytes\n", encodedSize);
20939 + tempBuf += encodedSize;
20940 + totalSize += encodedSize;
20942 + if (lblReqMsgCopy.pinningTlvExists) {
20943 + encodedSize = Mpls_encodeLdpPinningTlv(&(lblReqMsgCopy.pinningTlv),
20944 + tempBuf, bufSize - totalSize);
20945 + if (encodedSize < 0) {
20946 + return MPLS_ENC_PINNINGERROR;
20948 + PRINT_OUT("Encoded for Pinning Tlv %d bytes\n", encodedSize);
20949 + tempBuf += encodedSize;
20950 + totalSize += encodedSize;
20952 + if (lblReqMsgCopy.recClassTlvExists) {
20953 + encodedSize = Mpls_encodeLdpResClsTlv(&(lblReqMsgCopy.resClassTlv),
20954 + tempBuf, bufSize - totalSize);
20955 + if (encodedSize < 0) {
20956 + return MPLS_ENC_RESCLSERROR;
20958 + PRINT_OUT("Encoded for Resource class Tlv %d bytes\n", encodedSize);
20959 + tempBuf += encodedSize;
20960 + totalSize += encodedSize;
20962 + if (lblReqMsgCopy.preemptTlvExists) {
20963 + encodedSize = Mpls_encodeLdpPreemptTlv(&(lblReqMsgCopy.preemptTlv),
20964 + tempBuf, bufSize - totalSize);
20965 + if (encodedSize < 0) {
20966 + return MPLS_ENC_PREEMPTERROR;
20968 + PRINT_OUT("Encoded for Preempt Tlv %d bytes\n", encodedSize);
20969 + tempBuf += encodedSize;
20970 + totalSize += encodedSize;
20973 + return totalSize;
20975 +} /* End: Mpls_encodeLdpLblReqMsg */
20978 + * decode
20979 + */
20980 +int Mpls_decodeLdpLblReqMsg
20981 + (mplsLdpLblReqMsg_t * lblReqMsg, u_char * buff, int bufSize) {
20982 + int decodedSize = 0;
20983 + u_int totalSize = 0;
20984 + u_int stopLength = 0;
20985 + u_int totalSizeParam = 0;
20986 + u_char *tempBuf = buff; /* no change for the buff ptr */
20987 + mplsLdpTlv_t tlvTemp;
20989 + /*
20990 + * decode the base part of the pdu message
20991 + */
20992 + memset(lblReqMsg, 0, sizeof(mplsLdpLblReqMsg_t));
20993 + decodedSize = Mpls_decodeLdpBaseMsg(&(lblReqMsg->baseMsg), tempBuf, bufSize);
20994 + if (decodedSize < 0) {
20995 + return MPLS_DEC_BASEMSGERROR;
20997 + PRINT_OUT("Decode BaseMsg for Lbl Request on %d bytes\n", decodedSize);
20999 + if (lblReqMsg->baseMsg.flags.flags.msgType != MPLS_LBLREQ_MSGTYPE) {
21000 + PRINT_ERR("Not the right message type; expected lbl req and got %x\n",
21001 + lblReqMsg->baseMsg.flags.flags.msgType);
21002 + return MPLS_MSGTYPEERROR;
21005 + tempBuf += decodedSize;
21006 + totalSize += decodedSize;
21008 + if (bufSize - totalSize <= 0) {
21009 + /* nothing left for decoding */
21010 + PRINT_ERR("Lbl Request msg does not have anything beside base msg\n");
21011 + return totalSize;
21014 + PRINT_OUT
21015 + ("bufSize = %d, totalSize = %d, lblReqMsg->baseMsg.msgLength = %d\n",
21016 + bufSize, totalSize, lblReqMsg->baseMsg.msgLength);
21018 + /* Have to check the baseMsg.msgLength to know when to finish.
21019 + * We finsh when the totalSizeParam is >= to the base message length - the
21020 + * message id length (4)
21021 + */
21023 + stopLength = lblReqMsg->baseMsg.msgLength - MPLS_MSGIDFIXLEN;
21024 + while (stopLength > totalSizeParam) {
21025 + /*
21026 + * decode the tlv to check what's next
21027 + */
21028 + memset(&tlvTemp, 0, MPLS_TLVFIXLEN);
21029 + decodedSize = Mpls_decodeLdpTlv(&tlvTemp, tempBuf, bufSize - totalSize);
21030 + if (decodedSize < 0) {
21031 + /* something wrong */
21032 + PRINT_ERR("Label Request msg decode failed for tlv\n");
21033 + return MPLS_DEC_TLVERROR;
21036 + tempBuf += decodedSize;
21037 + totalSize += decodedSize;
21038 + totalSizeParam += decodedSize;
21040 + switch (tlvTemp.flags.flags.tBit) {
21041 + case MPLS_FEC_TLVTYPE:
21043 + decodedSize = Mpls_decodeLdpFecTlv(&(lblReqMsg->fecTlv),
21044 + tempBuf, bufSize - totalSize, tlvTemp.length);
21045 + if (decodedSize < 0) {
21046 + PRINT_ERR("Failure when decoding FEC tlv from LblReq msg\n");
21047 + return MPLS_DEC_FECERROR;
21049 + PRINT_OUT("Decoded for FEC %d bytes\n", decodedSize);
21050 + tempBuf += decodedSize;
21051 + totalSize += decodedSize;
21052 + totalSizeParam += decodedSize;
21054 + lblReqMsg->fecTlvExists = 1;
21055 + lblReqMsg->fecTlv.baseTlv = tlvTemp;
21056 + break;
21058 + case MPLS_HOPCOUNT_TLVTYPE:
21060 + decodedSize = Mpls_decodeLdpHopTlv(&(lblReqMsg->hopCountTlv),
21061 + tempBuf, bufSize - totalSize);
21062 + if (decodedSize < 0) {
21063 + PRINT_ERR("Failure when dec HopCount tlv from LblReq msg\n");
21064 + return MPLS_DEC_HOPCOUNTERROR;
21066 + PRINT_OUT("Decoded for HopCount %d bytes\n", decodedSize);
21067 + tempBuf += decodedSize;
21068 + totalSize += decodedSize;
21069 + totalSizeParam += decodedSize;
21071 + lblReqMsg->hopCountTlvExists = 1;
21072 + lblReqMsg->hopCountTlv.baseTlv = tlvTemp;
21073 + break;
21075 + case MPLS_PATH_TLVTYPE:
21077 + decodedSize = Mpls_decodeLdpPathVectorTlv(&(lblReqMsg->pathVecTlv),
21078 + tempBuf, bufSize - totalSize, tlvTemp.length);
21079 + if (decodedSize < 0) {
21080 + PRINT_ERR("Failure when dec Path Vec tlv from LblReq msg\n");
21081 + return MPLS_DEC_PATHVECERROR;
21083 + PRINT_OUT("Decoded for PATH VECTOR %d bytes\n", decodedSize);
21084 + tempBuf += decodedSize;
21085 + totalSize += decodedSize;
21086 + totalSizeParam += decodedSize;
21088 + lblReqMsg->pathVecTlvExists = 1;
21089 + lblReqMsg->pathVecTlv.baseTlv = tlvTemp;
21090 + break;
21092 + case MPLS_LBLMSGID_TLVTYPE:
21094 + lblReqMsg->lblMsgIdTlvExists = 1;
21095 + lblReqMsg->lblMsgIdTlv.baseTlv = tlvTemp;
21096 + break;
21098 + case MPLS_ER_TLVTYPE:
21100 + decodedSize = Mpls_decodeLdpERTlv(&(lblReqMsg->erTlv),
21101 + tempBuf, bufSize - totalSize, tlvTemp.length);
21102 + if (decodedSize < 0) {
21103 + PRINT_ERR("Failure when dec CR tlv from LblReq msg\n");
21104 + return MPLS_DEC_ERTLVERROR;
21106 + PRINT_OUT("Decoded for CR %d bytes\n", decodedSize);
21107 + tempBuf += decodedSize;
21108 + totalSize += decodedSize;
21109 + totalSizeParam += decodedSize;
21111 + lblReqMsg->erTlvExists = 1;
21112 + lblReqMsg->erTlv.baseTlv = tlvTemp;
21113 + break;
21115 + case MPLS_TRAFFIC_TLVTYPE:
21117 + decodedSize = Mpls_decodeLdpTrafficTlv(&(lblReqMsg->trafficTlv),
21118 + tempBuf, bufSize - totalSize, tlvTemp.length);
21119 + if (decodedSize < 0) {
21120 + PRINT_ERR("Failure when dec Traffic tlv from LblReq msg\n");
21121 + return MPLS_DEC_TRAFFICERROR;
21123 + PRINT_OUT("Decoded for Traffic %d bytes\n", decodedSize);
21124 + tempBuf += decodedSize;
21125 + totalSize += decodedSize;
21126 + totalSizeParam += decodedSize;
21128 + lblReqMsg->trafficTlvExists = 1;
21129 + lblReqMsg->trafficTlv.baseTlv = tlvTemp;
21130 + break;
21132 + case MPLS_LSPID_TLVTYPE:
21134 + decodedSize = Mpls_decodeLdpLspIdTlv(&(lblReqMsg->lspidTlv),
21135 + tempBuf, bufSize - totalSize);
21136 + if (decodedSize < 0) {
21137 + PRINT_ERR("Failure when dec LSPID tlv from LblReq msg\n");
21138 + return MPLS_DEC_LSPIDERROR;
21140 + PRINT_OUT("Decoded for lspid tlv %d bytes\n", decodedSize);
21141 + tempBuf += decodedSize;
21142 + totalSize += decodedSize;
21143 + totalSizeParam += decodedSize;
21145 + lblReqMsg->lspidTlvExists = 1;
21146 + lblReqMsg->lspidTlv.baseTlv = tlvTemp;
21147 + break;
21149 + case MPLS_PINNING_TLVTYPE:
21151 + decodedSize = Mpls_decodeLdpPinningTlv(&(lblReqMsg->pinningTlv),
21152 + tempBuf, bufSize - totalSize);
21153 + if (decodedSize < 0) {
21154 + PRINT_ERR("Failure when dec Pinning tlv from LblReq msg\n");
21155 + return MPLS_DEC_PINNINGERROR;
21157 + PRINT_OUT("Decoded for pining tlv %d bytes\n", decodedSize);
21158 + tempBuf += decodedSize;
21159 + totalSize += decodedSize;
21160 + totalSizeParam += decodedSize;
21162 + lblReqMsg->pinningTlvExists = 1;
21163 + lblReqMsg->pinningTlv.baseTlv = tlvTemp;
21164 + break;
21166 + case MPLS_RESCLASS_TLVTYPE:
21168 + decodedSize = Mpls_decodeLdpResClsTlv(&(lblReqMsg->resClassTlv),
21169 + tempBuf, bufSize - totalSize);
21170 + if (decodedSize < 0) {
21171 + PRINT_ERR("Failure when dec ResClass tlv from LblReq msg\n");
21172 + return MPLS_DEC_RESCLSERROR;
21174 + PRINT_OUT("Decoded for %d bytes\n", decodedSize);
21175 + tempBuf += decodedSize;
21176 + totalSize += decodedSize;
21177 + totalSizeParam += decodedSize;
21179 + lblReqMsg->recClassTlvExists = 1;
21180 + lblReqMsg->resClassTlv.baseTlv = tlvTemp;
21181 + break;
21183 + case MPLS_PREEMPT_TLVTYPE:
21185 + decodedSize = Mpls_decodeLdpPreemptTlv(&(lblReqMsg->preemptTlv),
21186 + tempBuf, bufSize - totalSize);
21187 + if (decodedSize < 0) {
21188 + PRINT_ERR("Failure when dec preempt tlv from LblReq msg\n");
21189 + return MPLS_DEC_PREEMPTERROR;
21191 + PRINT_OUT("Decoded for preempt tlv %d bytes\n", decodedSize);
21192 + tempBuf += decodedSize;
21193 + totalSize += decodedSize;
21194 + totalSizeParam += decodedSize;
21196 + lblReqMsg->preemptTlvExists = 1;
21197 + lblReqMsg->preemptTlv.baseTlv = tlvTemp;
21198 + break;
21200 + default:
21202 + PRINT_ERR("Found wrong type while decoding lbl req msg (%x)\n",
21203 + tlvTemp.flags.flags.tBit);
21204 + if (tlvTemp.flags.flags.uBit == 1) {
21205 + /* ignore the Tlv and continue processing */
21206 + tempBuf += tlvTemp.length;
21207 + totalSize += tlvTemp.length;
21208 + totalSizeParam += tlvTemp.length;
21209 + break;
21210 + } else {
21211 + /* drop the message; return error */
21212 + return MPLS_TLVTYPEERROR;
21215 + } /* switch type */
21217 + } /* while */
21219 + PRINT_OUT("totalsize for Mpls_decodeLdpLblReqMsg is %d\n", totalSize);
21220 + return totalSize;
21222 +} /*End: Mpls_decodeLdpLblReqMsg */
21224 +/*
21225 + * Encode for Label Withdraw and Label Release Message
21226 + */
21229 + * encode
21230 + */
21231 +int Mpls_encodeLdpLbl_W_R_Msg
21232 + (mplsLdpLbl_W_R_Msg_t * lbl_W_R_Msg, u_char * buff, int bufSize) {
21233 + mplsLdpLbl_W_R_Msg_t lbl_W_R_MsgCopy;
21234 + int encodedSize;
21235 + u_int totalSize = 0;
21236 + u_char *tempBuf = buff; /* no change for the buff ptr */
21238 + /* check the length of the messageId + param */
21239 + if ((int)(lbl_W_R_Msg->baseMsg.msgLength) + MPLS_TLVFIXLEN > bufSize) {
21240 + PRINT_ERR("failed to encode the lbl mapping msg: BUFFER TOO SMALL\n");
21241 + return MPLS_ENC_BUFFTOOSMALL;
21244 + lbl_W_R_MsgCopy = *lbl_W_R_Msg;
21246 + /*
21247 + * encode the base part of the pdu message
21248 + */
21249 + encodedSize = Mpls_encodeLdpBaseMsg(&(lbl_W_R_MsgCopy.baseMsg),
21250 + tempBuf, bufSize);
21251 + if (encodedSize < 0) {
21252 + return MPLS_ENC_BASEMSGERROR;
21254 + PRINT_OUT("Encode BaseMsg for label withdraw on %d bytes\n", encodedSize);
21255 + tempBuf += encodedSize;
21256 + totalSize += encodedSize;
21258 + /*
21259 + * encode the tlv if any
21260 + */
21261 + if (lbl_W_R_MsgCopy.fecTlvExists) {
21262 + encodedSize = Mpls_encodeLdpFecTlv(&(lbl_W_R_MsgCopy.fecTlv),
21263 + tempBuf, bufSize - totalSize);
21264 + if (encodedSize < 0) {
21265 + return MPLS_ENC_FECERROR;
21267 + PRINT_OUT("Encoded for FEC Tlv %d bytes\n", encodedSize);
21268 + tempBuf += encodedSize;
21269 + totalSize += encodedSize;
21272 + if (lbl_W_R_MsgCopy.genLblTlvExists) {
21273 + encodedSize = Mpls_encodeLdpGenLblTlv(&(lbl_W_R_MsgCopy.genLblTlv),
21274 + tempBuf, bufSize - totalSize);
21275 + if (encodedSize < 0) {
21276 + return MPLS_ENC_GENLBLERROR;
21278 + PRINT_OUT("Encoded for Generic Label Tlv %d bytes\n", encodedSize);
21279 + tempBuf += encodedSize;
21280 + totalSize += encodedSize;
21282 + if (lbl_W_R_MsgCopy.atmLblTlvExists) {
21283 + encodedSize = Mpls_encodeLdpAtmLblTlv(&(lbl_W_R_MsgCopy.atmLblTlv),
21284 + tempBuf, bufSize - totalSize);
21285 + if (encodedSize < 0) {
21286 + return MPLS_ENC_MAPATMERROR;
21288 + PRINT_OUT("Encoded for Atm Label Tlv %d bytes\n", encodedSize);
21289 + tempBuf += encodedSize;
21290 + totalSize += encodedSize;
21292 + if (lbl_W_R_MsgCopy.frLblTlvExists) {
21293 + encodedSize = Mpls_encodeLdpFrLblTlv(&(lbl_W_R_MsgCopy.frLblTlv),
21294 + tempBuf, bufSize - totalSize);
21295 + if (encodedSize < 0) {
21296 + return MPLS_ENC_FRLBLERROR;
21298 + PRINT_OUT("Encoded for Fr Label Tlv %d bytes\n", encodedSize);
21299 + tempBuf += encodedSize;
21300 + totalSize += encodedSize;
21302 + if (lbl_W_R_MsgCopy.lspidTlvExists) {
21303 + encodedSize = Mpls_encodeLdpLspIdTlv(&(lbl_W_R_MsgCopy.lspidTlv),
21304 + tempBuf, bufSize - totalSize);
21305 + if (encodedSize < 0) {
21306 + return MPLS_ENC_LSPIDERROR;
21308 + PRINT_OUT("Encoded for LSPID Tlv %d bytes\n", encodedSize);
21309 + tempBuf += encodedSize;
21310 + totalSize += encodedSize;
21313 + return totalSize;
21315 +} /* End: Mpls_encodeLdpLbl_W_R_Msg */
21318 + * decode
21319 + */
21320 +int Mpls_decodeLdpLbl_W_R_Msg
21321 + (mplsLdpLbl_W_R_Msg_t * lbl_W_R_Msg, u_char * buff, int bufSize) {
21322 + int decodedSize;
21323 + u_int totalSize = 0;
21324 + u_int stopLength = 0;
21325 + u_int totalSizeParam = 0;
21326 + u_char *tempBuf = buff; /* no change for the buff ptr */
21327 + mplsLdpTlv_t tlvTemp;
21329 + /*
21330 + * decode the base part of the pdu message
21331 + */
21332 + memset(lbl_W_R_Msg, 0, sizeof(mplsLdpLbl_W_R_Msg_t));
21333 + decodedSize = Mpls_decodeLdpBaseMsg(&(lbl_W_R_Msg->baseMsg),
21334 + tempBuf, bufSize);
21335 + if (decodedSize < 0) {
21336 + return MPLS_DEC_BASEMSGERROR;
21338 + PRINT_OUT("Decode BaseMsg for Lbl Withdraw on %d bytes\n", decodedSize);
21340 + if ((lbl_W_R_Msg->baseMsg.flags.flags.msgType != MPLS_LBLWITH_MSGTYPE) &&
21341 + (lbl_W_R_Msg->baseMsg.flags.flags.msgType != MPLS_LBLREL_MSGTYPE)) {
21342 + PRINT_ERR("Not the right message type; expected lbl W_R and got %x\n",
21343 + lbl_W_R_Msg->baseMsg.flags.flags.msgType);
21344 + return MPLS_MSGTYPEERROR;
21347 + tempBuf += decodedSize;
21348 + totalSize += decodedSize;
21350 + if (bufSize - totalSize <= 0) {
21351 + /* nothing left for decoding */
21352 + PRINT_ERR("Lbl Withdraw msg does not have anything beside base msg\n");
21353 + return totalSize;
21356 + PRINT_OUT
21357 + ("bufSize = %d, totalSize = %d, lbl_W_R_Msg->baseMsg.msgLength = %d\n",
21358 + bufSize, totalSize, lbl_W_R_Msg->baseMsg.msgLength);
21360 + /* Have to check the baseMsg.msgLength to know when to finish.
21361 + * We finsh when the totalSizeParam is >= to the base message length - the
21362 + * message id length (4)
21363 + */
21365 + stopLength = lbl_W_R_Msg->baseMsg.msgLength - MPLS_MSGIDFIXLEN;
21366 + while (stopLength > totalSizeParam) {
21367 + /*
21368 + * decode the tlv to check what's next
21369 + */
21370 + memset(&tlvTemp, 0, MPLS_TLVFIXLEN);
21371 + decodedSize = Mpls_decodeLdpTlv(&tlvTemp, tempBuf, bufSize - totalSize);
21372 + if (decodedSize < 0) {
21373 + /* something wrong */
21374 + PRINT_ERR("Label Mapping msg decode failed for tlv\n");
21375 + return MPLS_DEC_TLVERROR;
21378 + tempBuf += decodedSize;
21379 + totalSize += decodedSize;
21380 + totalSizeParam += decodedSize;
21382 + switch (tlvTemp.flags.flags.tBit) {
21383 + case MPLS_FEC_TLVTYPE:
21385 + decodedSize = Mpls_decodeLdpFecTlv(&(lbl_W_R_Msg->fecTlv),
21386 + tempBuf, bufSize - totalSize, tlvTemp.length);
21387 + if (decodedSize < 0) {
21388 + PRINT_ERR("Failure when decoding FEC tlv from LblWithdr msg\n");
21389 + return MPLS_DEC_FECERROR;
21391 + PRINT_OUT("Decoded for FEC %d bytes\n", decodedSize);
21392 + tempBuf += decodedSize;
21393 + totalSize += decodedSize;
21394 + totalSizeParam += decodedSize;
21396 + lbl_W_R_Msg->fecTlvExists = 1;
21397 + lbl_W_R_Msg->fecTlv.baseTlv = tlvTemp;
21398 + break;
21400 + case MPLS_GENLBL_TLVTYPE:
21402 + decodedSize = Mpls_decodeLdpGenLblTlv(&(lbl_W_R_Msg->genLblTlv),
21403 + tempBuf, bufSize - totalSize);
21404 + if (decodedSize < 0) {
21405 + PRINT_ERR("Failure when dec GEN Lbl tlv from LblWithdr msg\n");
21406 + return MPLS_DEC_GENLBLERROR;
21408 + PRINT_OUT("Decoded for Gen Lbl %d bytes\n", decodedSize);
21409 + tempBuf += decodedSize;
21410 + totalSize += decodedSize;
21411 + totalSizeParam += decodedSize;
21413 + lbl_W_R_Msg->genLblTlvExists = 1;
21414 + lbl_W_R_Msg->genLblTlv.baseTlv = tlvTemp;
21415 + break;
21417 + case MPLS_ATMLBL_TLVTYPE:
21419 + decodedSize = Mpls_decodeLdpAtmLblTlv(&(lbl_W_R_Msg->atmLblTlv),
21420 + tempBuf, bufSize - totalSize);
21421 + if (decodedSize < 0) {
21422 + PRINT_ERR("Failure when dec ATM Lbl tlv from LblWithdr msg\n");
21423 + return MPLS_DEC_MAPATMERROR;
21425 + PRINT_OUT("Decoded for Atm Lbl %d bytes\n", decodedSize);
21426 + tempBuf += decodedSize;
21427 + totalSize += decodedSize;
21428 + totalSizeParam += decodedSize;
21430 + lbl_W_R_Msg->atmLblTlvExists = 1;
21431 + lbl_W_R_Msg->atmLblTlv.baseTlv = tlvTemp;
21432 + break;
21434 + case MPLS_FRLBL_TLVTYPE:
21436 + decodedSize = Mpls_decodeLdpFrLblTlv(&(lbl_W_R_Msg->frLblTlv),
21437 + tempBuf, bufSize - totalSize);
21438 + if (decodedSize < 0) {
21439 + PRINT_ERR("Failure when dec FR Lbl tlv from LblWithdr msg\n");
21440 + return MPLS_DEC_FRLBLERROR;
21442 + PRINT_OUT("Decoded for Fr Lbl %d bytes\n", decodedSize);
21443 + tempBuf += decodedSize;
21444 + totalSize += decodedSize;
21445 + totalSizeParam += decodedSize;
21447 + lbl_W_R_Msg->frLblTlvExists = 1;
21448 + lbl_W_R_Msg->frLblTlv.baseTlv = tlvTemp;
21449 + break;
21451 + case MPLS_LSPID_TLVTYPE:
21453 + decodedSize = Mpls_decodeLdpLspIdTlv(&(lbl_W_R_Msg->lspidTlv),
21454 + tempBuf, bufSize - totalSize);
21455 + if (decodedSize < 0) {
21456 + PRINT_ERR("Failure when dec LSPID tlv from LblW_R msg\n");
21457 + return MPLS_DEC_LSPIDERROR;
21459 + PRINT_OUT("Decoded for lspid tlv %d bytes\n", decodedSize);
21460 + tempBuf += decodedSize;
21461 + totalSize += decodedSize;
21462 + totalSizeParam += decodedSize;
21464 + lbl_W_R_Msg->lspidTlvExists = 1;
21465 + lbl_W_R_Msg->lspidTlv.baseTlv = tlvTemp;
21466 + break;
21468 + default:
21470 + PRINT_ERR("Found wrong tlv type while decoding lbl withdr msg (%x)\n",
21471 + tlvTemp.flags.flags.tBit);
21472 + if (tlvTemp.flags.flags.uBit == 1) {
21473 + /* ignore the Tlv and continue processing */
21474 + tempBuf += tlvTemp.length;
21475 + totalSize += tlvTemp.length;
21476 + totalSizeParam += tlvTemp.length;
21477 + break;
21478 + } else {
21479 + /* drop the message; return error */
21480 + return MPLS_TLVTYPEERROR;
21483 + } /* switch type */
21485 + } /* while */
21487 + PRINT_OUT("totalsize for Mpls_decodeLdpLblWithdrawMsgIdTlv is %d\n",
21488 + totalSize);
21490 + return totalSize;
21492 +} /* End: Mpls_decodeLdpLbl_W_R_Msg */
21494 +/*
21495 + * Encode for CR Tlv
21496 + */
21499 + * encode
21500 + */
21501 +int Mpls_encodeLdpERTlv(mplsLdpErTlv_t * erTlv, u_char * buff, int bufSize)
21503 + int encodedSize = 0;
21504 + u_int totalSize = 0;
21505 + u_char *tempBuf = buff; /* no change for the buff ptr */
21506 + u_int i;
21508 + if (MPLS_TLVFIXLEN + (int)(erTlv->baseTlv.length) > bufSize) {
21509 + /* not enough room */
21510 + return MPLS_ENC_BUFFTOOSMALL;
21513 + /*
21514 + * encode for tlv
21515 + */
21516 + encodedSize = Mpls_encodeLdpTlv(&(erTlv->baseTlv), tempBuf, MPLS_TLVFIXLEN);
21517 + if (encodedSize < 0) {
21518 + return MPLS_ENC_TLVERROR;
21520 + tempBuf += encodedSize;
21521 + totalSize += encodedSize;
21523 + if (erTlv->numberErHops > MPLS_MAX_ER_HOPS) {
21524 + PRINT_ERR("MPLS_MAX_ER_HOPS is too small. Increase it if nec\n");
21525 + return MPLS_ER_HOPSNUMERROR;
21528 + /*
21529 + * encode for ER hops
21530 + */
21531 + for (i = 0; i < erTlv->numberErHops; i++) {
21532 + encodedSize = Mpls_encodeLdpErHop(&(erTlv->erHopArray[i]),
21533 + tempBuf, bufSize - totalSize, erTlv->erHopTypes[i]);
21534 + if (encodedSize < 0) {
21535 + return MPLS_ENC_ERHOPERROR;
21537 + tempBuf += encodedSize;
21538 + totalSize += encodedSize;
21541 + return totalSize;
21543 +} /* End: Mpls_encodeLdpERTlv */
21546 + * decode
21547 + */
21548 +int Mpls_decodeLdpERTlv
21549 + (mplsLdpErTlv_t * erTlv, u_char * buff, int bufSize, u_short tlvLength) {
21550 + u_char *tempBuf = buff; /* no change for the buff ptr */
21551 + u_char *erTlvPtr;
21552 + u_int i = 0;
21553 + int decodedSize = 0;
21554 + u_int erHopSize = 0; /* used to compute the sum of
21556 + all er hop elements + flags */
21557 + u_short type; /* filled in by Mpls_decodeLdpErHop
21559 + with the type of the ER hop
21560 + decoded */
21562 + if ((int)tlvLength > bufSize) {
21563 + /* not enough data for Fec elements tlv */
21564 + PRINT_ERR("failed decoding CR tlv \n");
21565 + return MPLS_DEC_BUFFTOOSMALL;
21568 + erTlvPtr = (u_char *) erTlv;
21569 + erTlvPtr += MPLS_TLVFIXLEN; /* we want to point to the flags since the
21570 + tlv was decoded before we reach here */
21572 + while (tlvLength > erHopSize) {
21573 + if (erTlv->numberErHops > (u_short) (MPLS_MAX_ER_HOPS - 1)) {
21574 + PRINT_ERR("MPLS_MAX_ER_HOPS is too small. Increase it if nec\n");
21575 + return MPLS_ER_HOPSNUMERROR;
21578 + decodedSize = Mpls_decodeLdpErHop(&(erTlv->erHopArray[i]),
21579 + tempBuf, bufSize - erHopSize, &type);
21580 + if (decodedSize < 0) {
21581 + return MPLS_DEC_ERHOPERROR;
21584 + erTlv->erHopTypes[i] = type;
21585 + erTlv->numberErHops++;
21586 + i++;
21588 + tempBuf += decodedSize;
21589 + erHopSize += decodedSize;
21591 + } /* end while */
21593 + return erHopSize;
21595 +} /* End: Mpls_decodeLdpERTlv */
21597 +/*
21598 + * Encode for ER Hop
21599 + */
21602 + * encode
21603 + */
21604 +int Mpls_encodeLdpErHop
21605 + (mplsLdpErHop_t * erHop, u_char * buff, int bufSize, u_short type) {
21606 + int encodedSize = 0;
21607 + u_char *tempBuff = buff;
21608 + u_char *startPtr;
21610 + switch (type) {
21611 + case MPLS_ERHOP_IPV4_TLVTYPE:
21613 + if (MPLS_ERHOP_IPV4_FIXLEN + MPLS_TLVFIXLEN > bufSize) {
21614 + return MPLS_ENC_BUFFTOOSMALL;
21617 + /* check how much is the preLen; should be between 0-32 */
21618 + if (erHop->erIpv4.flags.flags.preLen > 32) {
21619 + return MPLS_IPV4LENGTHERROR;
21622 + encodedSize = Mpls_encodeLdpTlv(&(erHop->erIpv4.baseTlv),
21623 + tempBuff, bufSize);
21624 + if (encodedSize < 0) {
21625 + return MPLS_ENC_TLVERROR;
21627 + tempBuff += encodedSize;
21628 + startPtr = (u_char *) & (erHop->erIpv4);
21629 + startPtr += encodedSize;
21631 + erHop->erIpv4.flags.flags.res = 0;
21632 + erHop->erIpv4.flags.mark = htonl(erHop->erIpv4.flags.mark);
21633 + erHop->erIpv4.address = htonl(erHop->erIpv4.address);
21635 + MEM_COPY(tempBuff, startPtr, MPLS_ERHOP_IPV4_FIXLEN);
21636 + encodedSize += MPLS_ERHOP_IPV4_FIXLEN;
21637 + break;
21639 + case MPLS_ERHOP_IPV6_TLVTYPE:
21641 + if (MPLS_ERHOP_IPV6_FIXLEN + MPLS_TLVFIXLEN > bufSize) {
21642 + return MPLS_ENC_BUFFTOOSMALL;
21644 + encodedSize = Mpls_encodeLdpTlv(&(erHop->erIpv6.baseTlv),
21645 + tempBuff, bufSize);
21646 + if (encodedSize < 0) {
21647 + return MPLS_ENC_TLVERROR;
21649 + tempBuff += encodedSize;
21650 + startPtr = (u_char *) & (erHop->erIpv6);
21651 + startPtr += encodedSize;
21653 + erHop->erIpv6.flags.flags.res = 0;
21654 + erHop->erIpv6.flags.mark = htonl(erHop->erIpv6.flags.mark);
21656 + MEM_COPY(tempBuff, startPtr, MPLS_ERHOP_IPV6_FIXLEN);
21658 + encodedSize += MPLS_ERHOP_IPV6_FIXLEN;
21659 + break;
21661 + case MPLS_ERHOP_AS_TLVTYPE:
21663 + if (MPLS_ERHOP_AS_FIXLEN + MPLS_TLVFIXLEN > bufSize) {
21664 + return MPLS_ENC_BUFFTOOSMALL;
21666 + encodedSize =
21667 + Mpls_encodeLdpTlv(&(erHop->erAs.baseTlv), tempBuff, bufSize);
21668 + if (encodedSize < 0) {
21669 + return MPLS_ENC_TLVERROR;
21671 + tempBuff += encodedSize;
21672 + startPtr = (u_char *) & (erHop->erAs);
21673 + startPtr += encodedSize;
21675 + erHop->erAs.flags.flags.res = 0;
21676 + erHop->erAs.flags.mark = htons(erHop->erAs.flags.mark);
21677 + erHop->erAs.asNumber = htons(erHop->erAs.asNumber);
21679 + MEM_COPY(tempBuff, startPtr, MPLS_ERHOP_AS_FIXLEN);
21681 + encodedSize += MPLS_ERHOP_AS_FIXLEN;
21682 + break;
21684 + case MPLS_ERHOP_LSPID_TLVTYPE:
21686 + if (MPLS_ERHOP_LSPID_FIXLEN + MPLS_TLVFIXLEN > bufSize) {
21687 + return MPLS_ENC_BUFFTOOSMALL;
21689 + encodedSize = Mpls_encodeLdpTlv(&(erHop->erLspId.baseTlv),
21690 + tempBuff, bufSize);
21691 + if (encodedSize < 0) {
21692 + return MPLS_ENC_TLVERROR;
21694 + tempBuff += encodedSize;
21695 + startPtr = (u_char *) & (erHop->erLspId);
21696 + startPtr += encodedSize;
21698 + erHop->erLspId.flags.flags.res = 0;
21699 + erHop->erLspId.flags.mark = htons(erHop->erLspId.flags.mark);
21700 + erHop->erLspId.lspid = htons(erHop->erLspId.lspid);
21701 + erHop->erLspId.routerId = htonl(erHop->erLspId.routerId);
21703 + MEM_COPY(tempBuff, startPtr, MPLS_ERHOP_LSPID_FIXLEN);
21705 + encodedSize += MPLS_ERHOP_LSPID_FIXLEN;
21706 + break;
21708 + default:
21710 + PRINT_ERR("Found wrong ER hop type while encoding FEC elem (%d)\n",
21711 + type);
21712 + return MPLS_ENC_ERHOPERROR;
21713 + break;
21715 + } /* end: switch */
21717 + return encodedSize;
21719 +} /* End: Mpls_encodeLdpErHop */
21722 + * decode
21723 + */
21724 +int Mpls_decodeLdpErHop
21725 + (mplsLdpErHop_t * erHop, u_char * buff, int bufSize, u_short * type) {
21726 + int decodedSize = 0;
21727 + u_char *tempBuf = buff;
21728 + u_char *startPtr;
21729 + mplsLdpTlv_t tlvTemp;
21731 + /*
21732 + * decode the tlv to check what is the type of the ER hop
21733 + */
21734 + decodedSize = Mpls_decodeLdpTlv(&tlvTemp, tempBuf, bufSize);
21735 + if (decodedSize < 0) {
21736 + /* something wrong */
21737 + PRINT_ERR("ErHop decode failed for tlv\n");
21738 + return MPLS_DEC_TLVERROR;
21740 + tempBuf += decodedSize;
21742 + switch (tlvTemp.flags.flags.tBit) {
21743 + case MPLS_ERHOP_IPV4_TLVTYPE:
21745 + if (MPLS_ERHOP_IPV4_FIXLEN > bufSize - MPLS_TLVFIXLEN) {
21746 + return MPLS_DEC_BUFFTOOSMALL;
21748 + startPtr = (u_char *) & (erHop->erIpv4);
21749 + startPtr += decodedSize; /* skip the tlv */
21751 + MEM_COPY(startPtr, tempBuf, MPLS_ERHOP_IPV4_FIXLEN);
21752 + erHop->erIpv4.flags.mark = ntohl(erHop->erIpv4.flags.mark);
21753 + erHop->erIpv4.address = ntohl(erHop->erIpv4.address);
21754 + erHop->erIpv4.baseTlv = tlvTemp;
21756 + /* check how much is the preLen; should be between 0-32 */
21757 + if (erHop->erIpv4.flags.flags.preLen > 32) {
21758 + return MPLS_IPV4LENGTHERROR;
21761 + decodedSize += MPLS_ERHOP_IPV4_FIXLEN;
21762 + break;
21764 + case MPLS_ERHOP_IPV6_TLVTYPE:
21766 + if (MPLS_ERHOP_IPV6_FIXLEN > bufSize - MPLS_TLVFIXLEN) {
21767 + return MPLS_DEC_BUFFTOOSMALL;
21769 + startPtr = (u_char *) & (erHop->erIpv6);
21770 + startPtr += decodedSize; /* skip the tlv */
21772 + MEM_COPY(startPtr, tempBuf, MPLS_ERHOP_IPV6_FIXLEN);
21773 + erHop->erIpv6.flags.mark = ntohl(erHop->erIpv6.flags.mark);
21774 + erHop->erIpv6.baseTlv = tlvTemp;
21776 + decodedSize += MPLS_ERHOP_IPV6_FIXLEN;
21777 + break;
21779 + case MPLS_ERHOP_AS_TLVTYPE:
21781 + if (MPLS_ERHOP_AS_FIXLEN > bufSize - MPLS_TLVFIXLEN) {
21782 + return MPLS_DEC_BUFFTOOSMALL;
21784 + startPtr = (u_char *) & (erHop->erAs);
21785 + startPtr += decodedSize; /* skip the tlv */
21787 + MEM_COPY(startPtr, tempBuf, MPLS_ERHOP_AS_FIXLEN);
21788 + erHop->erAs.flags.mark = ntohs(erHop->erAs.flags.mark);
21789 + erHop->erAs.asNumber = ntohs(erHop->erAs.asNumber);
21790 + erHop->erAs.baseTlv = tlvTemp;
21792 + decodedSize += MPLS_ERHOP_AS_FIXLEN;
21793 + break;
21795 + case MPLS_ERHOP_LSPID_TLVTYPE:
21797 + if (MPLS_ERHOP_LSPID_FIXLEN > bufSize - MPLS_TLVFIXLEN) {
21798 + return MPLS_DEC_BUFFTOOSMALL;
21800 + startPtr = (u_char *) & (erHop->erLspId);
21801 + startPtr += decodedSize; /* skip the tlv */
21803 + MEM_COPY(startPtr, tempBuf, MPLS_ERHOP_LSPID_FIXLEN);
21804 + erHop->erLspId.flags.mark = ntohs(erHop->erLspId.flags.mark);
21805 + erHop->erLspId.lspid = ntohs(erHop->erLspId.lspid);
21806 + erHop->erLspId.routerId = ntohl(erHop->erLspId.routerId);
21807 + erHop->erLspId.baseTlv = tlvTemp;
21809 + decodedSize += MPLS_ERHOP_LSPID_FIXLEN;
21810 + break;
21812 + default:
21814 + PRINT_ERR("Found wrong ER hop type while decoding ER (%d)\n", *type);
21815 + return MPLS_DEC_ERHOPERROR;
21816 + break;
21818 + } /* end: switch */
21820 + *type = tlvTemp.flags.flags.tBit;
21821 + return decodedSize;
21823 +} /* End: Mpls_decodeLdpErHop */
21825 +/*
21826 + * Encode for Traffic Tlv
21827 + */
21830 + * encode
21831 + */
21832 +int Mpls_encodeLdpTrafficTlv
21833 + (mplsLdpTrafficTlv_t * trafficTlv, u_char * buff, int bufSize) {
21834 + int encodedSize = 0;
21835 + u_char *tempBuf = buff; /* no change for the buff ptr */
21836 + u_char *trafficTlvPtr;
21837 + u_short tempLength; /* to store the tlv length for
21839 + later use */
21841 + if (MPLS_TLVFIXLEN + (int)(trafficTlv->baseTlv.length) > bufSize) {
21842 + /* not enough room */
21843 + return MPLS_ENC_BUFFTOOSMALL;
21846 + tempLength = trafficTlv->baseTlv.length;
21847 + /*
21848 + * encode for tlv
21849 + */
21850 + encodedSize = Mpls_encodeLdpTlv(&(trafficTlv->baseTlv),
21851 + tempBuf, MPLS_TLVFIXLEN);
21852 + if (encodedSize < 0) {
21853 + return MPLS_ENC_TLVERROR;
21855 + tempBuf += encodedSize;
21856 + trafficTlvPtr = (u_char *) trafficTlv;
21857 + trafficTlvPtr += encodedSize;
21859 + /*
21860 + * encode Traffic flags + Frequency + Reserved + Weight
21861 + */
21862 + encodedSize = sizeof(u_char) * 4;
21863 + MEM_COPY(tempBuf, trafficTlvPtr, encodedSize);
21864 + tempBuf += encodedSize;
21865 + trafficTlvPtr += encodedSize;
21867 + /*
21868 + * encode for Traffic parameters
21869 + */
21870 + if ((MPLS_TRAFFICPARAMLENGTH != sizeof(float)) ||
21871 + (sizeof(float) != sizeof(u_int))) {
21872 + PRINT_ERR("There is not compatibility for float type (%d)\n",
21874 + (int)sizeof(float));
21875 + return MPLS_FLOATTYPEERROR;
21878 + trafficTlv->pdr.mark = htonl(trafficTlv->pdr.mark);
21879 + trafficTlv->pbs.mark = htonl(trafficTlv->pbs.mark);
21880 + trafficTlv->cdr.mark = htonl(trafficTlv->cdr.mark);
21881 + trafficTlv->cbs.mark = htonl(trafficTlv->cbs.mark);
21882 + trafficTlv->ebs.mark = htonl(trafficTlv->ebs.mark);
21884 + MEM_COPY(tempBuf, trafficTlvPtr, MPLS_TRAFFICPARAMLENGTH * 5);
21886 + return (MPLS_TLVFIXLEN + tempLength);
21888 +} /* End: Mpls_encodeLdpTrafficTlv */
21891 + * decode
21892 + */
21893 +int Mpls_decodeLdpTrafficTlv
21894 + (mplsLdpTrafficTlv_t * trafficTlv,
21895 + u_char * buff, int bufSize, u_short tlvLength) {
21896 + u_char *tempBuf = buff; /* no change for the buff ptr */
21897 + int decodedSize = 0;
21898 + u_char *trafficTlvPtr;
21900 + if ((int)tlvLength > bufSize) {
21901 + /* not enough data for Fec elements tlv */
21902 + PRINT_ERR("failed decoding Traffic tlv \n");
21903 + return MPLS_DEC_BUFFTOOSMALL;
21905 + trafficTlvPtr = (u_char *) trafficTlv;
21906 + trafficTlvPtr += MPLS_TLVFIXLEN;
21908 + /*
21909 + * decode Traffic flags + Frequency + Reserved + Weight
21910 + */
21911 + decodedSize = sizeof(u_char) * 4;
21912 + MEM_COPY(trafficTlvPtr, tempBuf, decodedSize);
21913 + tempBuf += decodedSize;
21914 + trafficTlvPtr += decodedSize;
21916 + /*
21917 + * decode the traffic parameters
21918 + */
21919 + if (MPLS_TRAFFICPARAMLENGTH != sizeof(float)) {
21920 + PRINT_ERR("There is not compatibility for float type (%d)\n", decodedSize);
21921 + return MPLS_FLOATTYPEERROR;
21923 + MEM_COPY(trafficTlvPtr, tempBuf, MPLS_TRAFFICPARAMLENGTH * 5);
21925 + trafficTlv->pdr.mark = ntohl(trafficTlv->pdr.mark);
21926 + trafficTlv->pbs.mark = ntohl(trafficTlv->pbs.mark);
21927 + trafficTlv->cdr.mark = ntohl(trafficTlv->cdr.mark);
21928 + trafficTlv->cbs.mark = ntohl(trafficTlv->cbs.mark);
21929 + trafficTlv->ebs.mark = ntohl(trafficTlv->ebs.mark);
21931 + return tlvLength;
21933 +} /* End: Mpls_decodeLdpTrafficTlv */
21935 +/*
21936 + * Encode for Preempt Tlv
21937 + */
21940 + * encode
21941 + */
21942 +int Mpls_encodeLdpPreemptTlv
21943 + (mplsLdpPreemptTlv_t * preemptTlv, u_char * buff, int bufSize) {
21944 + int encodedSize = 0;
21945 + u_char *tempBuf = buff; /* no change for the buff ptr */
21946 + u_char *preemptTlvPtr;
21948 + if (MPLS_TLVFIXLEN + MPLS_PREEMPTTLV_FIXLEN > bufSize) {
21949 + /* not enough room */
21950 + return MPLS_ENC_BUFFTOOSMALL;
21953 + /*
21954 + * encode for tlv
21955 + */
21956 + encodedSize = Mpls_encodeLdpTlv(&(preemptTlv->baseTlv),
21957 + tempBuf, MPLS_TLVFIXLEN);
21958 + if (encodedSize < 0) {
21959 + return MPLS_ENC_TLVERROR;
21961 + tempBuf += encodedSize;
21963 + preemptTlv->res = 0;
21964 + preemptTlvPtr = (u_char *) preemptTlv;
21965 + preemptTlvPtr += encodedSize;
21967 + MEM_COPY(tempBuf, preemptTlvPtr, MPLS_PREEMPTTLV_FIXLEN);
21969 + return (MPLS_TLVFIXLEN + MPLS_PREEMPTTLV_FIXLEN);
21971 +} /* End: Mpls_encodeLdpPreemptTlv */
21974 + * decode
21975 + */
21976 +int Mpls_decodeLdpPreemptTlv
21977 + (mplsLdpPreemptTlv_t * preemptTlv, u_char * buff, int bufSize) {
21978 + u_char *preemptTlvPtr;
21980 + if (MPLS_PREEMPTTLV_FIXLEN > bufSize) {
21981 + PRINT_ERR("failed decoding preempt tlv\n");
21982 + return MPLS_DEC_BUFFTOOSMALL;
21984 + preemptTlvPtr = (u_char *) preemptTlv;
21985 + preemptTlvPtr += MPLS_TLVFIXLEN;
21987 + MEM_COPY(preemptTlvPtr, buff, MPLS_PREEMPTTLV_FIXLEN);
21989 + return MPLS_PREEMPTTLV_FIXLEN;
21991 +} /* End: Mpls_decodeLdpPreemptTlv */
21993 +/*
21994 + * Encode for LSPID Tlv
21995 + */
21998 + * encode
21999 + */
22000 +int Mpls_encodeLdpLspIdTlv
22001 + (mplsLdpLspIdTlv_t * lspIdTlv, u_char * buff, int bufSize) {
22002 + int encodedSize = 0;
22003 + u_char *tempBuf = buff; /* no change for the buff ptr */
22004 + u_char *lspIdTlvPtr;
22006 + if (MPLS_TLVFIXLEN + MPLS_LSPIDTLV_FIXLEN > bufSize) {
22007 + /* not enough room */
22008 + return MPLS_ENC_BUFFTOOSMALL;
22011 + /*
22012 + * encode for tlv
22013 + */
22014 + encodedSize = Mpls_encodeLdpTlv(&(lspIdTlv->baseTlv),
22015 + tempBuf, MPLS_TLVFIXLEN);
22016 + if (encodedSize < 0) {
22017 + return MPLS_ENC_TLVERROR;
22019 + tempBuf += encodedSize;
22021 + lspIdTlvPtr = (u_char *) lspIdTlv;
22022 + lspIdTlvPtr += encodedSize;
22024 + lspIdTlv->res = 0;
22025 + lspIdTlv->localCrlspId = htons(lspIdTlv->localCrlspId);
22026 + lspIdTlv->routerId = htonl(lspIdTlv->routerId);
22028 + MEM_COPY(tempBuf, lspIdTlvPtr, MPLS_LSPIDTLV_FIXLEN);
22030 + return (MPLS_TLVFIXLEN + MPLS_LSPIDTLV_FIXLEN);
22032 +} /* End: Mpls_encodeLdpLspIdTlv */
22035 + * decode
22036 + */
22037 +int Mpls_decodeLdpLspIdTlv
22038 + (mplsLdpLspIdTlv_t * lspIdTlv, u_char * buff, int bufSize) {
22039 + u_char *lspIdTlvPtr;
22041 + if (MPLS_PREEMPTTLV_FIXLEN > bufSize) {
22042 + PRINT_ERR("failed decoding LspId\n");
22043 + return MPLS_DEC_BUFFTOOSMALL;
22045 + lspIdTlvPtr = (u_char *) lspIdTlv;
22046 + lspIdTlvPtr += MPLS_TLVFIXLEN;
22048 + MEM_COPY(lspIdTlvPtr, buff, MPLS_LSPIDTLV_FIXLEN);
22050 + lspIdTlv->localCrlspId = ntohs(lspIdTlv->localCrlspId);
22051 + lspIdTlv->routerId = ntohl(lspIdTlv->routerId);
22053 + return MPLS_LSPIDTLV_FIXLEN;
22055 +} /* End: Mpls_decodeLdpLspIdTlv */
22057 +/*
22058 + * Encode for Resource Class Tlv
22059 + */
22062 + * encode
22063 + */
22064 +int Mpls_encodeLdpResClsTlv
22065 + (mplsLdpResClsTlv_t * resClsTlv, u_char * buff, int bufSize) {
22066 + int encodedSize = 0;
22067 + u_char *tempBuf = buff; /* no change for the buff ptr */
22069 + if (MPLS_TLVFIXLEN + (int)sizeof(u_int) > bufSize) {
22070 + /* not enough room */
22071 + return MPLS_ENC_BUFFTOOSMALL;
22074 + /*
22075 + * encode for tlv
22076 + */
22077 + encodedSize = Mpls_encodeLdpTlv(&(resClsTlv->baseTlv),
22078 + tempBuf, MPLS_TLVFIXLEN);
22079 + if (encodedSize < 0) {
22080 + return MPLS_ENC_TLVERROR;
22082 + tempBuf += encodedSize;
22084 + resClsTlv->rsCls = htonl(resClsTlv->rsCls);
22086 + MEM_COPY(tempBuf, (u_char *) & (resClsTlv->rsCls), sizeof(u_int));
22088 + return (MPLS_TLVFIXLEN + sizeof(u_int));
22090 +} /* End: Mpls_encodeLdpResClsTlv */
22093 + * decode
22094 + */
22095 +int Mpls_decodeLdpResClsTlv
22096 + (mplsLdpResClsTlv_t * resClsTlv, u_char * buff, int bufSize) {
22097 + if ((int)sizeof(u_int) > bufSize) {
22098 + PRINT_ERR("failed decoding resClass tlv\n");
22099 + return MPLS_DEC_BUFFTOOSMALL;
22102 + MEM_COPY((u_char *) & (resClsTlv->rsCls), buff, sizeof(u_int));
22103 + resClsTlv->rsCls = ntohl(resClsTlv->rsCls);
22105 + return sizeof(u_int);
22107 +} /* End: Mpls_decodeLdpResClsTlv */
22109 +/*
22110 + * Encode for Route Pinning Tlv
22111 + */
22114 + * encode
22115 + */
22116 +int Mpls_encodeLdpPinningTlv
22117 + (mplsLdpPinningTlv_t * pinningTlv, u_char * buff, int bufSize) {
22118 + int encodedSize = 0;
22119 + u_char *tempBuf = buff; /* no change for the buff ptr */
22121 + if (MPLS_TLVFIXLEN + (int)sizeof(u_int) > bufSize) {
22122 + /* not enough room */
22123 + return MPLS_ENC_BUFFTOOSMALL;
22126 + /*
22127 + * encode for tlv
22128 + */
22129 + encodedSize = Mpls_encodeLdpTlv(&(pinningTlv->baseTlv),
22130 + tempBuf, MPLS_TLVFIXLEN);
22131 + if (encodedSize < 0) {
22132 + return MPLS_ENC_TLVERROR;
22134 + tempBuf += encodedSize;
22136 + pinningTlv->flags.flags.res = 0;
22137 + pinningTlv->flags.mark = htonl(pinningTlv->flags.mark);
22139 + MEM_COPY(tempBuf, (u_char *) & (pinningTlv->flags.mark), sizeof(u_int));
22141 + return (MPLS_TLVFIXLEN + sizeof(u_int));
22143 +} /* End: Mpls_encodeLdpPinningTlv */
22146 + * decode
22147 + */
22148 +int Mpls_decodeLdpPinningTlv
22149 + (mplsLdpPinningTlv_t * pinningTlv, u_char * buff, int bufSize) {
22150 + if ((int)sizeof(u_int) > bufSize) {
22151 + PRINT_ERR("failed decoding route pinning tlv\n");
22152 + return MPLS_DEC_BUFFTOOSMALL;
22155 + MEM_COPY((u_char *) & (pinningTlv->flags.mark), buff, sizeof(u_int));
22156 + pinningTlv->flags.mark = ntohl(pinningTlv->flags.mark);
22158 + return sizeof(u_int);
22160 +} /* End: Mpls_decodeLdpPinningTlv */
22162 +/*
22163 + * Label Abort Request Message
22164 + */
22167 + * encode
22168 + */
22169 +int Mpls_encodeLdpLblAbortMsg
22170 + (mplsLdpLblAbortMsg_t * lblAbortMsg, u_char * buff, int bufSize) {
22171 + mplsLdpLblAbortMsg_t lblAbortMsgCopy;
22172 + int encodedSize = 0;
22173 + u_int totalSize = 0;
22174 + u_char *tempBuf = buff; /* no change for the buff ptr */
22176 + /* check the length of the messageId + param */
22177 + if ((int)(lblAbortMsg->baseMsg.msgLength) + MPLS_TLVFIXLEN > bufSize) {
22178 + PRINT_ERR("failed to encode the lbl abort request msg: BUFFER TOO SMALL\n");
22179 + return MPLS_ENC_BUFFTOOSMALL;
22182 + lblAbortMsgCopy = *lblAbortMsg;
22184 + /*
22185 + * encode the base part of the pdu message
22186 + */
22187 + encodedSize = Mpls_encodeLdpBaseMsg(&(lblAbortMsgCopy.baseMsg),
22188 + tempBuf, bufSize);
22189 + if (encodedSize < 0) {
22190 + return MPLS_ENC_BASEMSGERROR;
22192 + PRINT_OUT("Encode BaseMsg for label abort request msg on %d bytes\n",
22193 + encodedSize);
22194 + tempBuf += encodedSize;
22195 + totalSize += encodedSize;
22197 + /*
22198 + * encode the tlv if any
22199 + */
22200 + if (lblAbortMsgCopy.fecTlvExists) {
22201 + encodedSize = Mpls_encodeLdpFecTlv(&(lblAbortMsgCopy.fecTlv),
22202 + tempBuf, bufSize - totalSize);
22203 + if (encodedSize < 0) {
22204 + return MPLS_ENC_FECERROR;
22206 + PRINT_OUT("Encoded for FEC Tlv %d bytes\n", encodedSize);
22207 + tempBuf += encodedSize;
22208 + totalSize += encodedSize;
22210 + if (lblAbortMsgCopy.lblMsgIdTlvExists) {
22211 + encodedSize = Mpls_encodeLdpLblMsgIdTlv(&(lblAbortMsgCopy.lblMsgIdTlv),
22212 + tempBuf, bufSize - totalSize);
22213 + if (encodedSize < 0) {
22214 + return MPLS_ENC_LBLMSGIDERROR;
22216 + PRINT_OUT("Encoded for lbl request msg id Tlv %d bytes\n", encodedSize);
22217 + tempBuf += encodedSize;
22218 + totalSize += encodedSize;
22221 + return totalSize;
22223 +} /* End: Mpls_encodeLdpLblAbortMsg */
22226 + * decode
22227 + */
22228 +int Mpls_decodeLdpLblAbortMsg
22229 + (mplsLdpLblAbortMsg_t * lblAbortMsg, u_char * buff, int bufSize) {
22230 + int decodedSize = 0;
22231 + u_int totalSize = 0;
22232 + u_int stopLength = 0;
22233 + u_int totalSizeParam = 0;
22234 + u_char *tempBuf = buff; /* no change for the buff ptr */
22235 + mplsLdpTlv_t tlvTemp;
22237 + /*
22238 + * decode the base part of the pdu message
22239 + */
22240 + memset(lblAbortMsg, 0, sizeof(mplsLdpLblAbortMsg_t));
22241 + decodedSize = Mpls_decodeLdpBaseMsg(&(lblAbortMsg->baseMsg),
22242 + tempBuf, bufSize);
22243 + if (decodedSize < 0) {
22244 + return MPLS_DEC_BASEMSGERROR;
22246 + PRINT_OUT("Decode BaseMsg for Lbl Abort Request Msg on %d bytes\n",
22247 + decodedSize);
22249 + if (lblAbortMsg->baseMsg.flags.flags.msgType != MPLS_LBLABORT_MSGTYPE) {
22250 + PRINT_ERR("Not the right message type; expected lbl abort and got %x\n",
22251 + lblAbortMsg->baseMsg.flags.flags.msgType);
22252 + return MPLS_MSGTYPEERROR;
22255 + tempBuf += decodedSize;
22256 + totalSize += decodedSize;
22258 + if (bufSize - totalSize <= 0) {
22259 + /* nothing left for decoding */
22260 + PRINT_ERR("Lbl Abort msg does not have anything beside base msg\n");
22261 + return totalSize;
22264 + PRINT_OUT
22265 + ("bufSize = %d, totalSize = %d, lblAbortMsg->baseMsg.msgLength = %d\n",
22266 + bufSize, totalSize, lblAbortMsg->baseMsg.msgLength);
22268 + /* Have to check the baseMsg.msgLength to know when to finish.
22269 + * We finsh when the totalSizeParam is >= to the base message length - the
22270 + * message id length (4)
22271 + */
22273 + stopLength = lblAbortMsg->baseMsg.msgLength - MPLS_MSGIDFIXLEN;
22274 + while (stopLength > totalSizeParam) {
22275 + /*
22276 + * decode the tlv to check what's next
22277 + */
22278 + memset(&tlvTemp, 0, MPLS_TLVFIXLEN);
22279 + decodedSize = Mpls_decodeLdpTlv(&tlvTemp, tempBuf, bufSize - totalSize);
22280 + if (decodedSize < 0) {
22281 + /* something wrong */
22282 + PRINT_ERR("Label Abort msg decode failed for tlv\n");
22283 + return MPLS_DEC_TLVERROR;
22286 + tempBuf += decodedSize;
22287 + totalSize += decodedSize;
22288 + totalSizeParam += decodedSize;
22290 + switch (tlvTemp.flags.flags.tBit) {
22291 + case MPLS_FEC_TLVTYPE:
22293 + decodedSize = Mpls_decodeLdpFecTlv(&(lblAbortMsg->fecTlv),
22294 + tempBuf, bufSize - totalSize, tlvTemp.length);
22295 + if (decodedSize < 0) {
22296 + PRINT_ERR("Failure when decoding FEC tlv from LblAbort msg\n");
22297 + return MPLS_DEC_FECERROR;
22299 + PRINT_OUT("Decoded for FEC %d bytes\n", decodedSize);
22300 + tempBuf += decodedSize;
22301 + totalSize += decodedSize;
22302 + totalSizeParam += decodedSize;
22304 + lblAbortMsg->fecTlvExists = 1;
22305 + lblAbortMsg->fecTlv.baseTlv = tlvTemp;
22306 + break;
22308 + case MPLS_REQMSGID_TLVTYPE:
22310 + decodedSize = Mpls_decodeLdpLblMsgIdTlv(&(lblAbortMsg->lblMsgIdTlv),
22311 + tempBuf, bufSize - totalSize);
22312 + if (decodedSize < 0) {
22313 + PRINT_ERR("Failure when dec LblMsgId tlv from LblAbort msg\n");
22314 + return MPLS_DEC_LBLMSGIDERROR;
22316 + PRINT_OUT("Decoded for LblMsgId %d bytes\n", decodedSize);
22317 + tempBuf += decodedSize;
22318 + totalSize += decodedSize;
22319 + totalSizeParam += decodedSize;
22321 + lblAbortMsg->lblMsgIdTlvExists = 1;
22322 + lblAbortMsg->lblMsgIdTlv.baseTlv = tlvTemp;
22323 + break;
22325 + default:
22327 + PRINT_ERR("Found wrong tlv type while decoding lbl abort msg (%x)\n",
22328 + tlvTemp.flags.flags.tBit);
22329 + if (tlvTemp.flags.flags.uBit == 1) {
22330 + /* ignore the Tlv and continue processing */
22331 + tempBuf += tlvTemp.length;
22332 + totalSize += tlvTemp.length;
22333 + totalSizeParam += tlvTemp.length;
22334 + break;
22335 + } else {
22336 + /* drop the message; return error */
22337 + return MPLS_TLVTYPEERROR;
22340 + } /* switch type */
22342 + } /* while */
22344 + PRINT_OUT("totalsize for Mpls_decodeLdpLblAbortMsg is %d\n", totalSize);
22346 + return totalSize;
22348 +} /* End: Mpls_decodeLdpLblAbortMsg */
22351 + * DEBUG functions
22352 + */
22353 +void printTlv(mpls_instance_handle handle, mplsLdpTlv_t * tlv)
22355 + LDP_TRACE_OUT(handle, "\t Tlv:\n");
22356 + LDP_TRACE_OUT(handle, "\t BaseTlv: uBit = %d\n", tlv->flags.flags.uBit);
22357 + LDP_TRACE_OUT(handle, "\t\t fBit = %d\n", tlv->flags.flags.fBit);
22358 + LDP_TRACE_OUT(handle, "\t\t type = %x\n", tlv->flags.flags.tBit);
22359 + LDP_TRACE_OUT(handle, "\t\t length = %d\n", tlv->length);
22362 +void printHeader(mpls_instance_handle handle, mplsLdpHeader_t * header)
22364 + LDP_TRACE_OUT(handle, "LPD Header : protocolVersion = %d\n",
22365 + header->protocolVersion);
22366 + LDP_TRACE_OUT(handle, "\tpduLength = %d\n", header->pduLength);
22367 + LDP_TRACE_OUT(handle, "\tlsrAddress = %x\n", header->lsrAddress);
22368 + LDP_TRACE_OUT(handle, "\tlabelSpace = %x\n", header->labelSpace);
22371 +void printCspFlags(mpls_instance_handle handle, mplsLdpCspFlag_t * cspFlags)
22373 + LDP_TRACE_OUT(handle, "\tCSP Flags: lad = %d, ld = %d, pvl = %d, res = %d\n",
22374 + cspFlags->lad, cspFlags->ld, cspFlags->pvl, cspFlags->res);
22377 +void printCspFlagsPerByte(mpls_instance_handle handle, u_short * cspFlags)
22379 + u_char *ptr;
22381 + ptr = (u_char *) cspFlags;
22382 + LDP_TRACE_OUT(handle, "\tCSP Flags: (byte 0) %x\n", *ptr++);
22383 + LDP_TRACE_OUT(handle, "\t\t (byte 1) %x\n", *ptr);
22386 +void printCspTlv(mpls_instance_handle handle, mplsLdpCspTlv_t * csp)
22388 + LDP_TRACE_OUT(handle, "\tCSP:\n");
22389 + printTlv(handle, &(csp->baseTlv));
22390 + LDP_TRACE_OUT(handle, "\tcsp : protocolVersion = %d\n",
22391 + csp->protocolVersion);
22392 + LDP_TRACE_OUT(handle, "\t\tholdTime = %d\n", csp->holdTime);
22393 + LDP_TRACE_OUT(handle, "\t\tmaxPduLen = %d\n", csp->maxPduLen);
22394 + LDP_TRACE_OUT(handle, "\t\trcvLsrAddress = %08x\n", csp->rcvLsrAddress);
22395 + LDP_TRACE_OUT(handle, "\t\trcvLsId = %d\n", csp->rcvLsId);
22397 + printCspFlags(handle, &(csp->flags.flags));
22400 +void printAspFlags(mpls_instance_handle handle, mplsLdpSPFlag_t * aspFlags)
22402 + LDP_TRACE_OUT(handle,
22403 + "\t ASP Flags: mergeType = %d, numLblRng = %d, dir = %d, res = %d\n",
22404 + aspFlags->mergeType, aspFlags->numLblRng, aspFlags->dir, aspFlags->res);
22407 +void printAspFlagsPerByte(mpls_instance_handle handle, u_int * aspFlags)
22409 + u_char *ptr;
22411 + ptr = (u_char *) aspFlags;
22412 + LDP_TRACE_OUT(handle, "\tASP Flags: (byte 0) %x\n", *ptr++);
22413 + LDP_TRACE_OUT(handle, "\t\t (byte 1) %x\n", *ptr++);
22414 + LDP_TRACE_OUT(handle, "\t\t (byte 2) %x\n", *ptr++);
22415 + LDP_TRACE_OUT(handle, "\t\t (byte 3) %x\n", *ptr);
22418 +void printAtmLabel(mpls_instance_handle handle, mplsLdpAtmLblRng_t * label,
22419 + int i)
22421 + LDP_TRACE_OUT(handle,
22422 + "\tATM LABEL (%d) : res1 = %d, minVci = %d, minVpi = %d, res2 = %d, maxVci = %d, maxVpi = %d\n",
22423 + i, label->flags.flags.res1, label->flags.flags.minVci,
22424 + label->flags.flags.minVpi, label->flags.flags.res2,
22425 + label->flags.flags.maxVci, label->flags.flags.maxVpi);
22428 +void printAspTlv(mpls_instance_handle handle, mplsLdpAspTlv_t * asp)
22430 + int i = 0;
22432 + LDP_TRACE_OUT(handle, "\t asp:\n");
22433 + printTlv(handle, &(asp->baseTlv));
22434 + LDP_TRACE_OUT(handle, "\t asp labes (%d)\n",
22435 + (int)(asp->flags.flags.numLblRng));
22436 + for (i = 0; i < (int)(asp->flags.flags.numLblRng); i++) {
22437 + printAtmLabel(handle, &(asp->lblRngList[i]), i);
22439 + printAspFlags(handle, &(asp->flags.flags));
22442 +void printFspFlags(mpls_instance_handle handle, mplsLdpSPFlag_t * fspFlags)
22444 + LDP_TRACE_OUT(handle,
22445 + "\t FSP Flags: mergeType = %d, numLblRng = %d, dir = %d, res = %d\n",
22446 + fspFlags->mergeType, fspFlags->numLblRng, fspFlags->dir, fspFlags->res);
22449 +void printFspLabel(mpls_instance_handle handle, mplsLdpFrLblRng_t * label, int i)
22451 + LDP_TRACE_OUT(handle,
22452 + "\tFR LABEL (%d) : res_max = %d, maxDlci = %d, res_min = %d, len = %d minDlci = %d\n",
22453 + i, label->flags.flags.res_max, label->flags.flags.maxDlci,
22454 + label->flags.flags.res_min, label->flags.flags.len,
22455 + label->flags.flags.minDlci);
22458 +void printFspTlv(mpls_instance_handle handle, mplsLdpFspTlv_t * fsp)
22460 + int i = 0;
22462 + LDP_TRACE_OUT(handle, "\t fsp:\n");
22463 + printTlv(handle, &(fsp->baseTlv));
22464 + LDP_TRACE_OUT(handle, "\t fsp labes (%d)\n",
22465 + (int)(fsp->flags.flags.numLblRng));
22466 + for (i = 0; i < (int)(fsp->flags.flags.numLblRng); i++) {
22467 + printFspLabel(handle, &(fsp->lblRngList[i]), i);
22469 + printFspFlags(handle, &(fsp->flags.flags));
22472 +void printMsgBase(mpls_instance_handle handle, mplsLdpMsg_t * msg)
22474 + LDP_TRACE_OUT(handle, "\tbaseMsg : uBit = %d\n", msg->flags.flags.uBit);
22475 + LDP_TRACE_OUT(handle, "\t\t msgType = %x\n", msg->flags.flags.msgType);
22476 + LDP_TRACE_OUT(handle, "\t\t msgLength = %d\n", msg->msgLength);
22477 + LDP_TRACE_OUT(handle, "\t\t msgId = %d\n", msg->msgId);
22480 +void printInitMsg(mpls_instance_handle handle, mplsLdpInitMsg_t * initMsg)
22482 + LDP_TRACE_OUT(handle, "INIT MSG ***START***:\n");
22483 + printMsgBase(handle, &(initMsg->baseMsg));
22484 + if (initMsg->cspExists) {
22485 + printCspTlv(handle, &(initMsg->csp));
22486 + } else {
22487 + LDP_TRACE_OUT(handle, "\tINIT msg does NOT have CSP\n");
22489 + if (initMsg->aspExists) {
22490 + printAspTlv(handle, &(initMsg->asp));
22491 + } else {
22492 + LDP_TRACE_OUT(handle, "\tINIT msg does NOT have ASP\n");
22494 + if (initMsg->fspExists) {
22495 + printFspTlv(handle, &(initMsg->fsp));
22496 + } else {
22497 + LDP_TRACE_OUT(handle, "\tINIT msg does NOT have FSP\n");
22499 + LDP_TRACE_OUT(handle, "\nINIT MSG ***END***\n");
22502 +void printRetMsgTlv(mpls_instance_handle handle, mplsLdpRetMsgTlv_t * retMsg)
22504 + LDP_TRACE_OUT(handle, "\t retMsgTlv:\n");
22505 + printTlv(handle, &(retMsg->baseTlv));
22506 + LDP_TRACE_OUT(handle, "\t retMsgTlv.data is %s\n", retMsg->data);
22509 +void printRetPduTlv(mpls_instance_handle handle, mplsLdpRetPduTlv_t * retPdu)
22511 + LDP_TRACE_OUT(handle, "\t retPduTlv:\n");
22512 + printTlv(handle, &(retPdu->baseTlv));
22513 + LDP_TRACE_OUT(handle, "\t retPduTlv.data is %s\n", retPdu->data);
22516 +void printExStatusTlv(mpls_instance_handle handle, mplsLdpExStatusTlv_t * status)
22518 + LDP_TRACE_OUT(handle, "\t exStatusTlv:\n");
22519 + printTlv(handle, &(status->baseTlv));
22520 + LDP_TRACE_OUT(handle, "\t exStatus data: value = %d\n", status->value);
22523 +void printStatusTlv(mpls_instance_handle handle, mplsLdpStatusTlv_t * status)
22525 + LDP_TRACE_OUT(handle, "\t statusTlv:\n");
22526 + printTlv(handle, &(status->baseTlv));
22527 + LDP_TRACE_OUT(handle, "\t status data: msgId = %x\n", status->msgId);
22528 + LDP_TRACE_OUT(handle, "\t\t\tmsgType = %x\n", status->msgType);
22529 + LDP_TRACE_OUT(handle, "\t status Flags: error = %d\n",
22530 + status->flags.flags.error);
22531 + LDP_TRACE_OUT(handle, "\t\t\tforward = %d\n", status->flags.flags.forward);
22532 + LDP_TRACE_OUT(handle, "\t\t\tstatus = %d\n", status->flags.flags.status);
22535 +void printNotMsg(mpls_instance_handle handle, mplsLdpNotifMsg_t * notMsg)
22537 + LDP_TRACE_OUT(handle, "NOTIF MSG ***START***:\n");
22538 + printMsgBase(handle, &(notMsg->baseMsg));
22540 + if (notMsg->statusTlvExists) {
22541 + printStatusTlv(handle, &(notMsg->status));
22542 + } else {
22543 + LDP_TRACE_OUT(handle, "\tNotif msg does not have Status TLV\n");
22545 + if (notMsg->exStatusTlvExists) {
22546 + printExStatusTlv(handle, &(notMsg->exStatus));
22547 + } else {
22548 + LDP_TRACE_OUT(handle, "\tNotif msg does not have Extended Status TLV\n");
22550 + if (notMsg->retPduTlvExists) {
22551 + printRetPduTlv(handle, &(notMsg->retPdu));
22552 + } else {
22553 + LDP_TRACE_OUT(handle, "\tNotif msg does not have Return PDU\n");
22555 + if (notMsg->retMsgTlvExists) {
22556 + printRetMsgTlv(handle, &(notMsg->retMsg));
22557 + } else {
22558 + LDP_TRACE_OUT(handle, "\tNotif msg does not have Return MSG\n");
22560 + LDP_TRACE_OUT(handle, "NOTIF MSG ***END***:\n");
22563 +void printCsnTlv(mpls_instance_handle handle, mplsLdpCsnTlv_t * csn)
22565 + LDP_TRACE_OUT(handle, "\t csnTlv:\n");
22566 + printTlv(handle, &(csn->baseTlv));
22567 + LDP_TRACE_OUT(handle, "\t csnTlv data: value = %d\n", csn->seqNumber);
22570 +void printTrAdrTlv(mpls_instance_handle handle, mplsLdpTrAdrTlv_t * trAdr)
22572 + LDP_TRACE_OUT(handle, "\t trAdrTlv:\n");
22573 + printTlv(handle, &(trAdr->baseTlv));
22574 + LDP_TRACE_OUT(handle, "\t trAdrTlv data: value = %08x\n", trAdr->address);
22577 +void printChpTlv(mpls_instance_handle handle, mplsLdpChpTlv_t * chp)
22579 + LDP_TRACE_OUT(handle, "\t chpTlv:\n");
22580 + printTlv(handle, &(chp->baseTlv));
22581 + LDP_TRACE_OUT(handle, "\t chpTlv data: holdTime = %d\n", chp->holdTime);
22582 + LDP_TRACE_OUT(handle, "\t chpTlv Flags: target = %d\n",
22583 + chp->flags.flags.target);
22584 + LDP_TRACE_OUT(handle, "\t\t\trequest = %d\n", chp->flags.flags.request);
22585 + LDP_TRACE_OUT(handle, "\t\t\tres = %d\n", chp->flags.flags.res);
22588 +void printHelloMsg(mpls_instance_handle handle, mplsLdpHelloMsg_t * helloMsg)
22590 + LDP_TRACE_OUT(handle, "HELLO MSG ***START***:\n");
22591 + printMsgBase(handle, &(helloMsg->baseMsg));
22593 + if (helloMsg->chpTlvExists) {
22594 + printChpTlv(handle, &(helloMsg->chp));
22595 + } else {
22596 + LDP_TRACE_OUT(handle, "\tHello msg does not have Chp TLV\n");
22598 + if (helloMsg->trAdrTlvExists) {
22599 + printTrAdrTlv(handle, &(helloMsg->trAdr));
22600 + } else {
22601 + LDP_TRACE_OUT(handle, "\tHello msg does not have TrAdr TLV\n");
22603 + if (helloMsg->csnTlvExists) {
22604 + printCsnTlv(handle, &(helloMsg->csn));
22605 + } else {
22606 + LDP_TRACE_OUT(handle, "\tHello msg does not have Csn TLV\n");
22608 + LDP_TRACE_OUT(handle, "HELLO MSG ***END***:\n");
22611 +void printKeepAliveMsg(mpls_instance_handle handle,
22612 + mplsLdpKeepAlMsg_t * keepAliveMsg)
22614 + LDP_TRACE_OUT(handle, "KEEP ALIVE MSG ***START***:\n");
22615 + printMsgBase(handle, &(keepAliveMsg->baseMsg));
22616 + LDP_TRACE_OUT(handle, "KEEP ALIVE MSG ***END***:\n");
22619 +void printAdrListTlv(mpls_instance_handle handle, mplsLdpAdrTlv_t * adrList)
22621 + u_short i;
22622 + u_short length;
22624 + LDP_TRACE_OUT(handle, "\t adrListTlv:\n");
22625 + printTlv(handle, &(adrList->baseTlv));
22626 + LDP_TRACE_OUT(handle, "\t adrListTlv data: addrFamily = %x\n",
22627 + adrList->addrFamily);
22629 + /* get the current length of the encoding for addresses */
22631 + length = adrList->baseTlv.length - MPLS_ADDFAMFIXLEN;
22632 + LDP_TRACE_OUT(handle, "\t adrListTlv addresses (with %d addresses) :\n",
22633 + length / 4);
22634 + for (i = 0; i < (u_short) (length / 4); i++) {
22635 + if (i % 4 == 0) {
22636 + LDP_TRACE_OUT(handle, "\n\t\t\t");
22638 + LDP_TRACE_OUT(handle, "%02x ", adrList->address[i]);
22640 + LDP_TRACE_OUT(handle, "\n");
22643 +void printAddressMsg(mpls_instance_handle handle, mplsLdpAdrMsg_t * adrMsg)
22645 + if (adrMsg->baseMsg.flags.flags.msgType == MPLS_ADDR_MSGTYPE) {
22646 + LDP_TRACE_OUT(handle, "ADDRESS MSG ***START***:\n");
22647 + } else if (adrMsg->baseMsg.flags.flags.msgType == MPLS_ADDRWITH_MSGTYPE) {
22648 + LDP_TRACE_OUT(handle, "ADDRESS WITHDRAW MSG ***START***:\n");
22651 + printMsgBase(handle, &(adrMsg->baseMsg));
22653 + if (adrMsg->adrListTlvExists) {
22654 + printAdrListTlv(handle, &(adrMsg->addressList));
22655 + } else {
22656 + LDP_TRACE_OUT(handle, "\tAddress msg does not have addrList Tlv\n");
22658 + if (adrMsg->baseMsg.flags.flags.msgType == MPLS_ADDR_MSGTYPE) {
22659 + LDP_TRACE_OUT(handle, "ADDRESS MSG ***END***:\n");
22660 + } else if (adrMsg->baseMsg.flags.flags.msgType == MPLS_ADDRWITH_MSGTYPE) {
22661 + LDP_TRACE_OUT(handle, "ADDRESS WITHDRAW MSG ***END***:\n");
22665 +void printFecListTlv(mpls_instance_handle handle, mplsLdpFecTlv_t * fecTlv)
22667 + u_short i;
22669 + LDP_TRACE_OUT(handle, "\t fecTlv:\n");
22670 + printTlv(handle, &(fecTlv->baseTlv));
22671 + LDP_TRACE_OUT(handle, "\t\tfecTlv->numberFecElements = %d\n",
22672 + fecTlv->numberFecElements);
22673 + for (i = 0; i < fecTlv->numberFecElements; i++) {
22674 + LDP_TRACE_OUT(handle, "\t\telem %d type is %d\n", i,
22675 + fecTlv->fecElemTypes[i]);
22676 + if ((fecTlv->fecElemTypes[i] == 2) || (fecTlv->fecElemTypes[i] == 3)) {
22677 + LDP_TRACE_OUT(handle,
22678 + "\t\tFec Element : type = %d, addFam = %x, preLen = %d, address = %x\n",
22679 + fecTlv->fecElArray[i].addressEl.type,
22680 + fecTlv->fecElArray[i].addressEl.addressFam,
22681 + fecTlv->fecElArray[i].addressEl.preLen,
22682 + fecTlv->fecElArray[i].addressEl.address);
22685 + LDP_TRACE_OUT(handle, "\n");
22686 + LDP_TRACE_OUT(handle, "\tfecTlv.wcElemExists = %d\n", fecTlv->wcElemExists);
22690 +void printLblMsgIdTlv(mpls_instance_handle handle,
22691 + mplsLdpLblMsgIdTlv_t * lblMsgId)
22693 + LDP_TRACE_OUT(handle, "\t lblMsgIdTlv:\n");
22694 + printTlv(handle, &(lblMsgId->baseTlv));
22695 + LDP_TRACE_OUT(handle, "\t LblMsgId data: msgId = %d\n", lblMsgId->msgId);
22698 +void printPathVecTlv(mpls_instance_handle handle, mplsLdpPathTlv_t * pathVec)
22700 + u_int i, numlsrId;
22702 + LDP_TRACE_OUT(handle, "\t pathVecTlv:\n");
22703 + printTlv(handle, &(pathVec->baseTlv));
22704 + LDP_TRACE_OUT(handle, "\t PathVec data: ");
22706 + numlsrId = pathVec->baseTlv.length / 4;
22708 + for (i = 0; i < numlsrId; i++) {
22709 + if (i == 0) {
22710 + LDP_TRACE_OUT(handle, "lsrId[%d] = %x\n", i, pathVec->lsrId[i]);
22711 + } else {
22712 + LDP_TRACE_OUT(handle, "\t\t\tlsrId[%d] = %x\n", i, pathVec->lsrId[i]);
22715 + LDP_TRACE_OUT(handle, "\n");
22718 +void printHopTlv(mpls_instance_handle handle, mplsLdpHopTlv_t * hopCount)
22720 + LDP_TRACE_OUT(handle, "\t hopCountTlv:\n");
22721 + printTlv(handle, &(hopCount->baseTlv));
22722 + LDP_TRACE_OUT(handle, "\t hopCount data: hcValue = %d\n", hopCount->hcValue);
22725 +void printFrLblTlv(mpls_instance_handle handle, mplsLdpFrLblTlv_t * fr)
22727 + LDP_TRACE_OUT(handle, "\t frTlv :\n");
22728 + printTlv(handle, &(fr->baseTlv));
22729 + LDP_TRACE_OUT(handle, "\t Fr flags: res = %d\n", fr->flags.flags.res);
22730 + LDP_TRACE_OUT(handle, "\t\t len = %d\n", fr->flags.flags.len);
22731 + LDP_TRACE_OUT(handle, "\t\tdlci = %d\n", fr->flags.flags.dlci);
22734 +void printAtmLblTlv(mpls_instance_handle handle, mplsLdpAtmLblTlv_t * atm)
22736 + LDP_TRACE_OUT(handle, "\t atmTlv :\n");
22737 + printTlv(handle, &(atm->baseTlv));
22738 + LDP_TRACE_OUT(handle, "\t Atm flags: res = %d\n", atm->flags.flags.res);
22739 + LDP_TRACE_OUT(handle, "\t\t v = %d\n", atm->flags.flags.v);
22740 + LDP_TRACE_OUT(handle, "\t\tvpi = %d\n", atm->flags.flags.vpi);
22741 + LDP_TRACE_OUT(handle, "\t Atm data : vci = %d\n", atm->vci);
22744 +void printGenLblTlv(mpls_instance_handle handle, mplsLdpGenLblTlv_t * genLbl)
22746 + LDP_TRACE_OUT(handle, "\t genLblTlv:\n");
22747 + printTlv(handle, &(genLbl->baseTlv));
22748 + LDP_TRACE_OUT(handle, "\t genLbl data: label = %d\n", genLbl->label);
22751 +void printLlbMapMsg(mpls_instance_handle handle, mplsLdpLblMapMsg_t * lblMapMsg)
22753 + LDP_TRACE_OUT(handle, "LABEL MAPPING MSG ***START***:\n");
22754 + printMsgBase(handle, &(lblMapMsg->baseMsg));
22756 + if (lblMapMsg->fecTlvExists) {
22757 + printFecListTlv(handle, &(lblMapMsg->fecTlv));
22758 + } else {
22759 + LDP_TRACE_OUT(handle, "\tLabel mapping msg does not have fec Tlv\n");
22761 + if (lblMapMsg->genLblTlvExists) {
22762 + printGenLblTlv(handle, &(lblMapMsg->genLblTlv));
22763 + } else {
22764 + LDP_TRACE_OUT(handle, "\tLabel mapping msg does not have gen label Tlv\n");
22766 + if (lblMapMsg->atmLblTlvExists) {
22767 + printAtmLblTlv(handle, &(lblMapMsg->atmLblTlv));
22768 + } else {
22769 + LDP_TRACE_OUT(handle, "\tLabel mapping msg does not have atm label Tlv\n");
22771 + if (lblMapMsg->frLblTlvExists) {
22772 + printFrLblTlv(handle, &(lblMapMsg->frLblTlv));
22773 + } else {
22774 + LDP_TRACE_OUT(handle, "\tLabel mapping msg does not have fr label Tlv\n");
22776 + if (lblMapMsg->hopCountTlvExists) {
22777 + printHopTlv(handle, &(lblMapMsg->hopCountTlv));
22778 + } else {
22779 + LDP_TRACE_OUT(handle, "\tLabel mapping msg does not have hop count Tlv\n");
22781 + if (lblMapMsg->pathVecTlvExists) {
22782 + printPathVecTlv(handle, &(lblMapMsg->pathVecTlv));
22783 + } else {
22784 + LDP_TRACE_OUT(handle,
22785 + "\tLabel mapping msg does not have path vector Tlv\n");
22787 + if (lblMapMsg->lblMsgIdTlvExists) {
22788 + printLblMsgIdTlv(handle, &(lblMapMsg->lblMsgIdTlv));
22789 + } else {
22790 + LDP_TRACE_OUT(handle,
22791 + "\tLabel mapping msg does not have label messageId Tlv\n");
22793 + if (lblMapMsg->lspidTlvExists) {
22794 + printLspIdTlv(handle, &(lblMapMsg->lspidTlv));
22795 + } else {
22796 + LDP_TRACE_OUT(handle, "\tLabel mapping msg does not have LSPID Tlv\n");
22798 + if (lblMapMsg->trafficTlvExists) {
22799 + printTrafficTlv(handle, &(lblMapMsg->trafficTlv));
22800 + } else {
22801 + LDP_TRACE_OUT(handle, "\tLabel mapping msg does not have traffic Tlv\n");
22803 + LDP_TRACE_OUT(handle, "LABEL MAPPING MSG ***END***:\n");
22806 +void printErFlags(mpls_instance_handle handle, mplsLdpErFlag_t * flags)
22808 + LDP_TRACE_OUT(handle, "\t\tER FLAGS: l = %d, res = %d\n",
22809 + flags->l, flags->res);
22812 +void printErIPFlags(mpls_instance_handle handle, mplsLdpErIPFlag_t * flags)
22814 + LDP_TRACE_OUT(handle, "\t\tER IP FLAGS: l = %d, res = %d, preLen = %d\n",
22815 + flags->l, flags->res, flags->preLen);
22818 +void printErHop(mpls_instance_handle handle, mplsLdpErHop_t * erHop,
22819 + u_short type)
22821 + int i;
22823 + switch (type) {
22824 + case MPLS_ERHOP_IPV4_TLVTYPE:
22826 + printErIPFlags(handle, &(erHop->erIpv4.flags.flags));
22827 + LDP_TRACE_OUT(handle, "\t\t IPv4: address = %x\n",
22828 + erHop->erIpv4.address);
22829 + break;
22831 + case MPLS_ERHOP_IPV6_TLVTYPE:
22833 + printErIPFlags(handle, &(erHop->erIpv6.flags.flags));
22834 + LDP_TRACE_OUT(handle, "\t\t IPv6: address ");
22835 + for (i = 0; i < MPLS_IPV6ADRLENGTH; i++) {
22836 + LDP_TRACE_OUT(handle, "\t\t a[%d] = %x\n", i,
22837 + erHop->erIpv6.address[i]);
22839 + break;
22841 + case MPLS_ERHOP_AS_TLVTYPE:
22843 + printErFlags(handle, &(erHop->erAs.flags.flags));
22844 + LDP_TRACE_OUT(handle, "\t\t ASnumber: asNumber = %d\n",
22845 + erHop->erAs.asNumber);
22846 + break;
22848 + case MPLS_ERHOP_LSPID_TLVTYPE:
22850 + printErFlags(handle, &(erHop->erLspId.flags.flags));
22851 + LDP_TRACE_OUT(handle, "\t\t LSPID: lspid = %d, routerId = %d\n",
22852 + erHop->erLspId.lspid, erHop->erLspId.routerId);
22853 + break;
22855 + default:
22857 + LDP_TRACE_OUT(handle, "UNKNWON ER HOP type = %d\n", type);
22862 +void printErTlv(mpls_instance_handle handle, mplsLdpErTlv_t * erTlv)
22864 + u_short i;
22866 + LDP_TRACE_OUT(handle, "\t erTlv:\n");
22867 + printTlv(handle, &(erTlv->baseTlv));
22868 + LDP_TRACE_OUT(handle, "\t erTlv has %d ErHops\n", erTlv->numberErHops);
22869 + for (i = 0; i < erTlv->numberErHops; i++) {
22870 + LDP_TRACE_OUT(handle, "\tTYPE[%i] = %x\n", i, erTlv->erHopTypes[i]);
22871 + printErHop(handle, &(erTlv->erHopArray[i]), erTlv->erHopTypes[i]);
22875 +void printTrafficFlags(mpls_instance_handle handle,
22876 + mplsLdpTrafficFlag_t * traflag)
22878 + LDP_TRACE_OUT(handle,
22879 + "\t\tTraffic flags: res = %d, F6 = %d, F5 = %d, F4 = %d, F3 = %d, F2 = %d, F1 = %d\n",
22880 + traflag->res, traflag->f6Bit, traflag->f5Bit, traflag->f4Bit,
22881 + traflag->f3Bit, traflag->f2Bit, traflag->f1Bit);
22884 +void printTrafficTlv(mpls_instance_handle handle,
22885 + mplsLdpTrafficTlv_t * trafficTlv)
22887 + LDP_TRACE_OUT(handle, "\t trafficTlv:\n");
22888 + printTlv(handle, &(trafficTlv->baseTlv));
22889 + printTrafficFlags(handle, &(trafficTlv->flags.flags));
22890 + LDP_TRACE_OUT(handle,
22891 + "\t trafficTlv data: freq = %d, res = %d, weight = %d\n", trafficTlv->freq,
22892 + trafficTlv->res, trafficTlv->weight);
22893 + LDP_TRACE_OUT(handle, "\t trafficTlv param: \n");
22894 + LDP_TRACE_OUT(handle, "\t\t PDR = %f (%x)\n", trafficTlv->pdr.pdr,
22895 + *(u_int *) & (trafficTlv->pdr.pdr));
22896 + LDP_TRACE_OUT(handle, "\t\t PBS = %f (%x)\n", trafficTlv->pbs.pbs,
22897 + *(u_int *) & (trafficTlv->pbs.pbs));
22898 + LDP_TRACE_OUT(handle, "\t\t CDR = %f (%x)\n", trafficTlv->cdr.cdr,
22899 + *(u_int *) & (trafficTlv->cdr.cdr));
22900 + LDP_TRACE_OUT(handle, "\t\t CBS = %f (%x)\n", trafficTlv->cbs.cbs,
22901 + *(u_int *) & (trafficTlv->cbs.cbs));
22902 + LDP_TRACE_OUT(handle, "\t\t EBS = %f (%x)\n", trafficTlv->ebs.ebs,
22903 + *(u_int *) & (trafficTlv->ebs.ebs));
22906 +void printLlbReqMsg(mpls_instance_handle handle, mplsLdpLblReqMsg_t * lblReqMsg)
22908 + LDP_TRACE_OUT(handle, "LABEL REQUEST MSG ***START***:\n");
22909 + printMsgBase(handle, &(lblReqMsg->baseMsg));
22911 + if (lblReqMsg->fecTlvExists) {
22912 + printFecListTlv(handle, &(lblReqMsg->fecTlv));
22913 + } else {
22914 + LDP_TRACE_OUT(handle, "\tLabel request msg does not have fec Tlv\n");
22916 + if (lblReqMsg->hopCountTlvExists) {
22917 + printHopTlv(handle, &(lblReqMsg->hopCountTlv));
22918 + } else {
22919 + LDP_TRACE_OUT(handle, "\tLabel request msg does not have hop count Tlv\n");
22921 + if (lblReqMsg->pathVecTlvExists) {
22922 + printPathVecTlv(handle, &(lblReqMsg->pathVecTlv));
22923 + } else {
22924 + LDP_TRACE_OUT(handle,
22925 + "\tLabel request msg does not have path vector Tlv\n");
22927 + if (lblReqMsg->lblMsgIdTlvExists) {
22928 + printTlv(handle, &(lblReqMsg->lblMsgIdTlv.baseTlv));
22929 + } else {
22930 + LDP_TRACE_OUT(handle,
22931 + "\tLabel request msg does not have return msgId Tlv\n");
22933 + if (lblReqMsg->erTlvExists) {
22934 + printErTlv(handle, &(lblReqMsg->erTlv));
22935 + } else {
22936 + LDP_TRACE_OUT(handle, "\tLabel request msg does not have cr Tlv\n");
22938 + if (lblReqMsg->trafficTlvExists) {
22939 + printTrafficTlv(handle, &(lblReqMsg->trafficTlv));
22940 + } else {
22941 + LDP_TRACE_OUT(handle, "\tLabel request msg does not have traffic Tlv\n");
22943 + if (lblReqMsg->lspidTlvExists) {
22944 + printLspIdTlv(handle, &(lblReqMsg->lspidTlv));
22945 + } else {
22946 + LDP_TRACE_OUT(handle, "\tLabel request msg does not have LSPID Tlv\n");
22948 + if (lblReqMsg->pinningTlvExists) {
22949 + printPinningTlv(handle, &(lblReqMsg->pinningTlv));
22950 + } else {
22951 + LDP_TRACE_OUT(handle, "\tLabel request msg does not have Pinning Tlv\n");
22953 + if (lblReqMsg->recClassTlvExists) {
22954 + printResClsTlv(handle, &(lblReqMsg->resClassTlv));
22955 + } else {
22956 + LDP_TRACE_OUT(handle, "\tLabel request msg does not have ResClass Tlv\n");
22958 + if (lblReqMsg->preemptTlvExists) {
22959 + printPreemptTlv(handle, &(lblReqMsg->preemptTlv));
22960 + } else {
22961 + LDP_TRACE_OUT(handle, "\tLabel request msg does not have Preempt Tlv\n");
22963 + LDP_TRACE_OUT(handle, "LABEL REQUEST MSG ***END***:\n");
22966 +void printLbl_W_R_Msg(mpls_instance_handle handle, mplsLdpLbl_W_R_Msg_t * msg)
22968 + if (msg->baseMsg.flags.flags.msgType == MPLS_LBLWITH_MSGTYPE) {
22969 + LDP_TRACE_OUT(handle, "LABEL WITHDRAW MSG ***START***:\n");
22970 + } else if (msg->baseMsg.flags.flags.msgType == MPLS_LBLREL_MSGTYPE) {
22971 + LDP_TRACE_OUT(handle, "LABEL RELEASE MSG ***START***:\n");
22973 + printMsgBase(handle, &(msg->baseMsg));
22975 + if (msg->fecTlvExists) {
22976 + printFecListTlv(handle, &(msg->fecTlv));
22977 + } else {
22978 + LDP_TRACE_OUT(handle, "\tLabel msg does not have fec Tlv\n");
22980 + if (msg->genLblTlvExists) {
22981 + printGenLblTlv(handle, &(msg->genLblTlv));
22982 + } else {
22983 + LDP_TRACE_OUT(handle, "\tLabel msg does not have gen Tlv\n");
22985 + if (msg->atmLblTlvExists) {
22986 + printAtmLblTlv(handle, &(msg->atmLblTlv));
22987 + } else {
22988 + LDP_TRACE_OUT(handle, "\tLabel msg does not have atm Tlv\n");
22990 + if (msg->frLblTlvExists) {
22991 + printFrLblTlv(handle, &(msg->frLblTlv));
22992 + } else {
22993 + LDP_TRACE_OUT(handle, "\tLabel msg does not have fr Tlv\n");
22995 + if (msg->lspidTlvExists) {
22996 + printLspIdTlv(handle, &(msg->lspidTlv));
22997 + } else {
22998 + LDP_TRACE_OUT(handle, "\tLabel msg does not have LSPID Tlv\n");
23000 + if (msg->baseMsg.flags.flags.msgType == MPLS_LBLWITH_MSGTYPE) {
23001 + LDP_TRACE_OUT(handle, "LABEL WITHDRAW MSG *** END ***:\n");
23002 + } else if (msg->baseMsg.flags.flags.msgType == MPLS_LBLREL_MSGTYPE) {
23003 + LDP_TRACE_OUT(handle, "LABEL RELEASE MSG *** END ***:\n");
23007 +void printPreemptTlv(mpls_instance_handle handle,
23008 + mplsLdpPreemptTlv_t * preemptTlv)
23010 + LDP_TRACE_OUT(handle, "\t preemptTlv:\n");
23011 + printTlv(handle, &(preemptTlv->baseTlv));
23012 + LDP_TRACE_OUT(handle,
23013 + "\t preemptTlv data: setPrio = %d, holdPrio = %d, res = %d\n",
23014 + preemptTlv->setPrio, preemptTlv->holdPrio, preemptTlv->res);
23017 +void printResClsTlv(mpls_instance_handle handle, mplsLdpResClsTlv_t * tlv)
23019 + LDP_TRACE_OUT(handle, "\t resClsTlv:\n");
23020 + printTlv(handle, &(tlv->baseTlv));
23021 + LDP_TRACE_OUT(handle, "\t resClsTlv data: rsCls = %x\n", tlv->rsCls);
23024 +void printLspIdTlv(mpls_instance_handle handle, mplsLdpLspIdTlv_t * tlv)
23026 + LDP_TRACE_OUT(handle, "\t lspIdTlv:\n");
23027 + printTlv(handle, &(tlv->baseTlv));
23028 + LDP_TRACE_OUT(handle,
23029 + "\t lspIdTlv data: res = %d, localCrlspId = %d, routerId = %x\n", tlv->res,
23030 + tlv->localCrlspId, tlv->routerId);
23033 +void printPinningTlv(mpls_instance_handle handle, mplsLdpPinningTlv_t * tlv)
23035 + LDP_TRACE_OUT(handle, "\t pinningTlv:\n");
23036 + printTlv(handle, &(tlv->baseTlv));
23037 + LDP_TRACE_OUT(handle, "\t pinningTlv data: pBit = %d, res = %d\n",
23038 + tlv->flags.flags.pBit, tlv->flags.flags.res);
23041 +void printLlbAbortMsg(mpls_instance_handle handle, mplsLdpLblAbortMsg_t * lblMsg)
23043 + LDP_TRACE_OUT(handle, "LABEL ABORT MSG ***START***:\n");
23044 + printMsgBase(handle, &(lblMsg->baseMsg));
23046 + if (lblMsg->fecTlvExists) {
23047 + printFecListTlv(handle, &(lblMsg->fecTlv));
23048 + } else {
23049 + LDP_TRACE_OUT(handle, "\tLabel abort msg does not have fec Tlv\n");
23051 + if (lblMsg->lblMsgIdTlvExists) {
23052 + printLblMsgIdTlv(handle, &(lblMsg->lblMsgIdTlv));
23053 + } else {
23054 + LDP_TRACE_OUT(handle,
23055 + "\tLabel abort msg does not have label messageId Tlv\n");
23057 + LDP_TRACE_OUT(handle, "LABEL ABORT MSG ***END***:\n");
23060 +/*
23061 + * Routine to convert hex string to ascii string
23062 + */
23064 +int converHexToAscii(u_char * buffHex, int buffHexLen, u_char * buffAscii)
23066 + /* convert the hexEncrypP hex string to a char sting */
23067 + int i = 0;
23068 + int j = 0;
23069 + char c, c1;
23070 + u_char *p = buffHex;
23071 + u_char *q = buffAscii;
23073 + for (i = 0; i < buffHexLen; i += 2, j++) {
23074 + c = *p;
23075 + p++;
23076 + c1 = *p;
23077 + p++;
23078 + if (c >= '0' && c <= '9')
23079 + c -= '0';
23080 + else if (c >= 'A' && c <= 'F')
23081 + c -= 'A' - 0xa;
23082 + else if (c >= 'a' && c <= 'f')
23083 + c -= 'a' - 0xa;
23084 + else
23085 + return 0;
23086 + if (c1 >= '0' && c1 <= '9')
23087 + c1 -= '0';
23088 + else if (c1 >= 'A' && c1 <= 'F')
23089 + c1 -= 'A' - 0xa;
23090 + else if (c1 >= 'a' && c1 <= 'f')
23091 + c1 -= 'a' - 0xa;
23092 + else
23093 + return 0;
23095 + *q++ = (c << 4) + (c1 & 0x0f);
23097 + return j;
23099 +} /* End : converHexToAscii */
23101 +/*
23102 + * Routine to convert ascii string to hex string
23103 + */
23104 +int converAsciiToHex(u_char * buffHex, int buffAsciiLen, u_char * buffAscii)
23106 + int i;
23107 + u_char *p2 = buffHex;
23108 + u_char *p1 = buffAscii;
23109 + u_char buf[3];
23111 + for (i = 0; i < buffAsciiLen; i++) {
23112 + memset(buf, 0, 3);
23113 + sprintf((char *)buf, "%02x", *p1++);
23114 + memcpy(p2, buf, 2);
23115 + p2 += strlen((char *)buf);
23117 + *p2 = '\0';
23119 + p2 = buffHex;
23120 + for (i = 0; i < 2 * buffAsciiLen; i++) {
23121 + PRINT_OUT("%c", *p2++);
23123 + PRINT_OUT("\n");
23124 + return i;
23126 +} /* End : converAsciiToHex */
23128 +/*****************************************************************************
23129 +* This section includes one example of hex buffers which contains encoding *
23130 +* for a pdu header and a request message. *
23131 +* *
23132 +* the hex buffer for the request message contains (where q represents the end*
23133 +* of the buffer): *
23134 +* *
23135 +* 0001009AC00003050002040100900000000806010000010000100200011B00194059030001 *
23136 +* 042F7D308308210008000000013A1D65030800003008040008000000193A1D651708040008 *
23137 +* 800000053A1D6503080400088000000F3A1D650D08040008000000233A1D65210810001824 *
23138 +* 01000040e3333342c8000040e00000447a0000412000000823000480000000082200040ABC *
23139 +* DEFF0820000407070000q *
23140 +* *
23141 +* Make sure that when copy and paste the buffer, there are no new line chars *
23142 +* or blanks. *
23143 +* When decoding the above buffer, the following debug output should show if *
23144 +* the debug flag is defined and set: *
23145 +* *
23146 +*LPD Header : protocolVersion = 1 *
23147 +* pduLength = 154 *
23148 +* lsrAddress = c0000305 *
23149 +* labelSpace = 2 *
23150 +* *
23151 +*LABEL REQUEST MSG ***START***: *
23152 +* baseMsg : msgType = 401 *
23153 +* msgLength = 144 *
23154 +* msgId = 8 *
23155 +* fecTlv: *
23156 +* Tlv: *
23157 +* BaseTlv: type = 100 *
23158 +* length = 16 *
23159 +* uBit = 0 *
23160 +* fBit = 0 *
23161 +* fecTlv->numberFecElements = 2 *
23162 +* elem 0 type is 2 *
23163 +* Fec Element : type = 2, addFam = 1, preLen = 27, *
23164 +* address = 194059 *
23165 +* elem 1 type is 3 *
23166 +* Fec Element : type = 3, addFam = 1, preLen = 4, *
23167 +* address = 2f7d3083 *
23168 +* *
23169 +* fecTlv.wcElemExists = 0 *
23170 +* Label request msg does not have cos label Tlv *
23171 +* Label request msg does not have hop count Tlv *
23172 +* Label request msg does not have path vector Tlv *
23173 +* Tlv: *
23174 +* BaseTlv: type = 601 *
23175 +* length = 0 *
23176 +* uBit = 0 *
23177 +* fBit = 0 *
23178 +* erTlv: *
23179 +* Tlv: *
23180 +* BaseTlv: type = 800 *
23181 +* length = 48 *
23182 +* uBit = 0 *
23183 +* fBit = 0 *
23184 +* erTlv has 4 ErHops *
23185 +* TYPE[0] = 804 *
23186 +* ER FLAGS: l = 0, res = 0 *
23187 +* LSPID: lspid = 25, routerId = 975004951 *
23188 +* TYPE[1] = 804 *
23189 +* ER FLAGS: l = 1, res = 0 *
23190 +* LSPID: lspid = 5, routerId = 975004931 *
23191 +* TYPE[2] = 804 *
23192 +* ER FLAGS: l = 1, res = 0 *
23193 +* LSPID: lspid = 15, routerId = 975004941 *
23194 +* TYPE[3] = 804 *
23195 +* ER FLAGS: l = 0, res = 0 *
23196 +* LSPID: lspid = 35, routerId = 975004961 *
23197 +* trafficTlv: *
23198 +* Tlv: *
23199 +* BaseTlv: type = 810 *
23200 +* length = 24 *
23201 +* uBit = 0 *
23202 +* fBit = 0 *
23203 +* Traffic flags: res = 0, F6 = 1, F5 = 0, F4 = 0, F3 = 1, *
23204 +* F2 = 0, F1 = 0 *
23205 +* trafficTlv data: freq = 1, res = 0, weight = 0 *
23206 +* trafficTlv param: *
23207 +* PDR = 7.1(40e33333) *
23208 +* PBS = 100.0(42c80000) *
23209 +* CDR = 7.0(40e00000) *
23210 +* CBS = 1000.0(447a0000) *
23211 +* EBS = 10.0(41200000) *
23212 +* lspIdTlv: *
23213 +* Tlv: *
23214 +* BaseTlv: type = 821 *
23215 +* length = 8 *
23216 +* uBit = 0 *
23217 +* fBit = 0 *
23218 +* lspIdTlv data: res = 0, localCrlspId = 1, routerId = 3a1d6503 *
23219 +* pinningTlv: *
23220 +* Tlv: *
23221 +* BaseTlv: type = 823 *
23222 +* length = 4 *
23223 +* uBit = 0 *
23224 +* fBit = 0 *
23225 +* pinningTlv data: pBit = 1, res = 0 *
23226 +* resClsTlv: *
23227 +* Tlv: *
23228 +* BaseTlv: type = 822 *
23229 +* length = 4 *
23230 +* uBit = 0 *
23231 +* fBit = 0 *
23232 +* resClsTlv data: rsCls = abcdeff *
23233 +* preemptTlv: *
23234 +* Tlv: *
23235 +* BaseTlv: type = 820 *
23236 +* length = 4 *
23237 +* uBit = 0 *
23238 +* fBit = 0 *
23239 +* preemptTlv data: setPrio = 7, holdPrio = 7, res = 0 *
23240 +*LABEL REQUEST MSG ***END***: *
23241 +*****************************************************************************/
23242 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_nortel.h quagga-mpls/ldpd/ldp_nortel.h
23243 --- quagga/ldpd/ldp_nortel.h 1969-12-31 18:00:00.000000000 -0600
23244 +++ quagga-mpls/ldpd/ldp_nortel.h 2006-08-09 21:56:10.000000000 -0500
23245 @@ -0,0 +1,1830 @@
23246 +#ifndef _LDP_MPLS_H_
23247 +#define _LDP_MPLS_H_
23249 +/******************************************************************************
23250 +* Nortel Networks Software License *
23251 +* *
23252 +* READ THE TERMS OF THIS LICENSE CAREFULLY. BY USING, MODIFYING, OR *
23253 +* DISTRIBUTING THIS SOFTWARE AND ANY ACCOMPANYING DOCUMENTATION (COLLECTIVELY,*
23254 +* "SOFTWARE") YOU ARE AGREEING TO ALL OF THE TERMS OF THIS LICENSE. *
23255 +* *
23256 +* 1. Nortel Telecom Limited, on behalf of itself and its subsidiaries *
23257 +* (collectively "Nortel Networks") grants to you a non-exclusive, perpetual, *
23258 +* world-wide right to use, copy, modify, and distribute the Software at no *
23259 +* charge. *
23260 +* *
23261 +* 2. You may sublicense recipients of redistributed Software to use, *
23262 +* copy, modify, and distribute the Software on substantially the same terms as*
23263 +* this License. You may not impose any further restrictions on the *
23264 +* recipient's exercise of the rights in the Software granted under this *
23265 +* License. Software distributed to other parties must be accompanied by a *
23266 +* License containing a grant, disclaimer and limitation of liability *
23267 +* substantially in the form of 3, 4, and 5 below provided that references to *
23268 +* "Nortel Networks" may be changed to "Supplier". *
23269 +* *
23270 +* 3. Nortel Networks reserves the right to modify and release new *
23271 +* versions of the Software from time to time which may include modifications *
23272 +* made by third parties like you. Accordingly, you agree that you shall *
23273 +* automatically grant a license to Nortel Networks to include, at its option, *
23274 +* in any new version of the Software any modifications to the Software made by*
23275 +* you and made available directly or indirectly to Nortel Networks. Nortel *
23276 +* Networks shall have the right to use, copy, modify, and distribute any such *
23277 +* modified Software on substantially the same terms as this License. *
23278 +* *
23279 +* 4. THE SOFTWARE IS PROVIDED ON AN "AS IS" BASIS. NORTEL NETWORKS AND *
23280 +* ITS AGENTS AND SUPPLIERS DISCLAIM ALL REPRESENTATIONS, WARRANTIES AND *
23281 +* CONDITIONS RELATING TO THE SOFTWARE, INCLUDING, BUT NOT LIMITED TO, IMPLIED *
23282 +* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
23283 +* NON-INFRINGEMENT OF THIRD-PARTY INTELLECTUAL PROPERTY RIGHTS. NORTEL *
23284 +* NETWORKS AND ITS AGENTS AND SUPPLIERS DO NOT WARRANT, GUARANTEE, OR MAKE ANY*
23285 +* REPRESENTATIONS REGARDING THE USE, OR THE RESULTS OF THE USE, OF THE *
23286 +* SOFTWARE IN TERMS OR CORRECTNESS, ACCURACY, RELIABILITY, CURRENTNESS, OR *
23287 +* OTHERWISE. *
23288 +* *
23289 +* 5. NEITHER NORTEL NETWORKS NOR ANY OF ITS AGENTS OR SUPPLIERS SHALL BE *
23290 +* LIABLE FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR EXEMPLARY *
23291 +* DAMAGES, OR ECONOMIC LOSSES (INCLUDING DAMAGES FOR LOSS OF BUSINESS PROFITS,*
23292 +* BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION AND THE LIKE), ARISING *
23293 +* FROM THE SOFTWARE OR THIS LICENSE AGREEMENT, EVEN IF NORTEL NETWORKS OR SUCH*
23294 +* AGENT OR SUPPLIER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES OR *
23295 +* LOSSES, AND WHETHER ANY SUCH DAMAGE OR LOSS ARISES OUT OF CONTRACT, TORT, OR*
23296 +* OTHERWISE. *
23297 +* *
23298 +* 6. This License shall be governed by the laws of the Province of *
23299 +* Ontario, Canada. *
23300 +*******************************************************************************/
23302 +/******************************************************************************
23303 + * This file contains the C implementation for encode/decode functions *
23304 + * for the following types of messages: notification, hello, initialization, *
23305 + * keepAlive, address, address Withdraw, label Mapping, label Request, label *
23306 + * Withdraw and label Release. There are also encode/decode methods for all *
23307 + * tlv types required by the previously enumerated messages. *
23308 + * Please remember that the pdu will always contain the header followed by 1 *
23309 + * or more LDP messages. The file contains functions to encode/decode the LDP *
23310 + * header as well. *
23311 + * All the messages, header message and the tlvs are in conformity with the *
23312 + * draft-ietf-mpls-ldp-04 (May 1999) and with draft-ietf-mpls-cr-ldp-01 *
23313 + * (Jan 1999). *
23314 + * *
23315 + * Please note that the U bit in the message and the F bit in the tlv are *
23316 + * ignored in this version of the code. *
23317 + * *
23318 + * Please note that the traffic parameters for traffic TLV have to be IEEE *
23319 + * single precision floating point numbers. *
23320 + * *
23321 + * Please note that there might be a small chance for bit field manipulation *
23322 + * portability inconsistency. If such problems occure, the code requires *
23323 + * changes for a suitable bit-field manipulation. The code for encoding and *
23324 + * decoding makes the assumption that the compiler packs the bit fields in a *
23325 + * structure into adjacent bits of the same unit. *
23326 + * *
23327 + * The usage of the encode/decode functions is described below. *
23328 + * *
23329 + * The encode functions take as arguments: a pointer to the structure which *
23330 + * implements msg/tlv, a buffer (where the encoding is done) and the buffer *
23331 + * length. *
23332 + * If the encode is successfull, the function returns the total encoded *
23333 + * length. *
23334 + * If the encode fails, the function returns an error code. *
23335 + * The encode functions for messages and message headers do not modify the *
23336 + * content of the struct which is to be encoded. All the other encode *
23337 + * functions will change the content of the structure. The pointer which *
23338 + * points to the beginning of the buffer is not changed. *
23339 + * *
23340 + * The decode functions take as arguments: a pointer to the structure which *
23341 + * is going to be populated after decoding, a pointer to a buffer and the *
23342 + * buffer length. *
23343 + * If the decode is successful, the function returns the total decoded length *
23344 + * If the decode fails, the function returns an error code. The decode *
23345 + * functions do not modify the pointer to the buffer which contains the data *
23346 + * to be decoded. *
23347 + * *
23348 + * Example on how to use the encode/decode functions for a keepAlive message: *
23349 + * *
23350 + * Encode the keep alive message: *
23351 + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ *
23352 + * u_char buffer[500]; *
23353 + * int returnCode; *
23354 + * struct mplsLdpKeepAlMsg_s keepAliveMsg; *
23355 + * keepAliveMsg.baseMsg.msgType = MPLS_KEEPAL_MSGTYPE; *
23356 + * keepAliveMsg.baseMsg.msgLength = MPLS_MSGIDFIXLEN; *
23357 + * keepAliveMsg.baseMsg.msgId = 123; *
23358 + * bzero(buffer, 500); *
23359 + * returnCode = Mpls_encodeLdpKeepAliveMsg(&keepAliveMsg, *
23360 + * buffer, *
23361 + * 500); *
23362 + * if (returnCode < 0) *
23363 + * check the error code *
23364 + * else *
23365 + * write(fd, buffer, returnCode); *
23366 + * *
23367 + * *
23368 + * Decode the keep alive meesage: *
23369 + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ *
23370 + * u_char buffer[500]; *
23371 + * int returnCode; *
23372 + * struct mplsLdpKeepAlMsg_s keepAliveMsg; *
23373 + * read(fd, buffer, length); *
23374 + * returnCode = Mpls_decodeLdpKeepAliveMsg(&keepAliveMsg, *
23375 + * buffer, *
23376 + * 500); *
23377 + * if (returnCode < 0) *
23378 + * check the error code *
23379 + * else *
23380 + * { *
23381 + * printKeepAliveMsg(&keepAliveMsg); *
23382 + * } *
23383 + * *
23384 + * An example on how to use the decode functions for the header and the *
23385 + * messages can be found in the main function. *
23386 + * *
23387 + * The code was tested for big endian and little endian for sparc5, linux *
23388 + * and i960. *
23389 + * *
23390 + * In order to compile for little endian, the LITTLE_ENDIAN_BYTE_ORDER should *
23391 + * be defined. *
23392 + * *
23393 + * At the end of this file there is an examples of a hex buffers and its *
23394 + * corresponding values. *
23395 + * *
23396 + * *
23397 + * Version History *
23398 + * Version Date Authors Description *
23399 + * =========== ======== ========= ====================== *
23400 + * mpls_encdec_01.c 99/03/15 Antonela Paraschiv draft-ietf-mpls-ldp-03 and *
23401 + * draft-ietf-mpls-cr-ldp-01 *
23402 + * *
23403 + * mpls_encdec_02.c 99/05/19 Antonela Paraschiv draft-ietf-mpls-ldp-04 and *
23404 + * draft-ietf-mpls-cr-ldp-01 *
23405 + * *
23406 + ******************************************************************************/
23408 +#include "ldp_struct.h"
23409 +#include "mpls_bitfield.h"
23410 +#include <sys/types.h>
23411 +#include <string.h>
23413 +#define MEM_COPY(X, Y, Z) memcpy(X, Y, Z)
23415 +/* macros used to decode the entire LDP; they declare local var for
23416 + different type of messages */
23418 +/* debug macros */
23419 +#define PRINT_OUT(args...) LDP_PRINT(NULL,args)
23420 +#define PRINT_ERR(args...) LDP_PRINT(NULL,args)
23423 + * MESSAGE TYPE CONSTANS & TLV CONSTANTS
23424 + */
23426 +#define MPLS_LDP_HDRSIZE 10 /* the size for mpls ldp hdr */
23427 +#define MPLS_TLVFIXLEN 4 /* type + len */
23428 +#define MPLS_MSGIDFIXLEN 4 /* type + len */
23429 +#define MPLS_LDPIDLEN 6
23430 +#define MPLS_PDUMAXLEN 4096 /* octets */
23431 +#define MPLS_VERSION 0x0001
23432 +#define MPLS_IPV4ADDRFAMILYN 0x0100 /* rfc 1700 (network order) */
23433 +#define MPLS_INIFINITE_TIMEVAL 0xfffff
23435 +/* for initialize message */
23436 +#define MPLS_INIT_MSGTYPE 0x0200 /* initialization msg */
23437 +#define MPLS_CSP_TLVTYPE 0x0500 /* common params for init msg */
23438 +#define MPLS_ASP_TLVTYPE 0x0501 /* atm session params */
23439 +#define MPLS_FSP_TLVTYPE 0x0502 /* frame relay session params */
23440 +#define MPLS_ASPFIXLEN 4 /* M + N + D + res */
23441 +#define MPLS_FSPFIXLEN 4 /* M + N + res */
23442 +#define MPLS_CSPFIXLEN 14 /* protocolV + ... + ldp ids */
23443 +#define MPLS_ATMLBLMAXLEN 10
23444 +#define MPLS_ATMLRGFIXLEN 8
23445 +#define MPLS_FRLRGFIXLEN 8
23446 +#define MPLS_ASP_NOMERGE 0
23447 +#define MPLS_ASP_VPMERGE 1
23448 +#define MPLS_ASP_VCMERGE 2
23449 +#define MPLS_ASP_VPVCMERGE 3
23450 +#define MPLS_FRLBLMAXLEN 10
23451 +#define MPLS_FRDLCI10BITS 0
23452 +#define MPLS_FRDLCI17BITS 1
23453 +#define MPLS_FRDLCI23BITS 2
23455 +/* for notification message */
23456 +#define MPLS_NOT_MSGTYPE 0x0001 /* notification msg */
23457 +#define MPLS_NOT_ST_TLVTYPE 0x0300 /* status tlv for not msg */
23458 +#define MPLS_NOT_ES_TLVTYPE 0x0301 /* extended status for not msg */
23459 +#define MPLS_NOT_RP_TLVTYPE 0x0302 /* returned PDU for not msg */
23460 +#define MPLS_NOT_RM_TLVTYPE 0x0303 /* returned msg for not msg */
23461 +#define MPLS_STATUSFIXLEN 10 /* status code + id + type */
23462 +#define MPLS_EXSTATUSLEN 4
23463 +#define MPLS_NOT_MAXSIZE MPLS_PDUMAXLEN - MPLS_TLVFIXLEN - \
23464 + MPLS_MSGIDFIXLEN
23466 +/* for hello message */
23467 +#define MPLS_HELLO_MSGTYPE 0x0100 /* hello msg */
23468 +#define MPLS_CHP_TLVTYPE 0x0400 /* Common Hello Param Tlv */
23469 +#define MPLS_TRADR_TLVTYPE 0x0401 /* Transport Address Param Tlv */
23470 +#define MPLS_CSN_TLVTYPE 0x0402 /* Conf Seq Number Param Tlv */
23471 +#define MPLS_CHPFIXLEN 4
23472 +#define MPLS_CSNFIXLEN 4
23473 +#define MPLS_TRADRFIXLEN 4
23475 +/* for keep alive message */
23476 +#define MPLS_KEEPAL_MSGTYPE 0x0201 /* keep alive msg */
23478 +/* for address messages */
23479 +#define MPLS_ADDR_MSGTYPE 0x0300 /* address msg */
23480 +#define MPLS_ADDRWITH_MSGTYPE 0x0301 /* address withdraw msg */
23481 +#define MPLS_ADDRLIST_TLVTYPE 0x0101 /* addrss list tlv type */
23482 +#define MPLS_IPv4LEN 4
23483 +#define MPLS_ADDFAMFIXLEN 2
23484 +#define MPLS_ADDLISTMAXLEN (MPLS_PDUMAXLEN - (2*MPLS_TLVFIXLEN) - \
23485 + MPLS_MSGIDFIXLEN - MPLS_ADDFAMFIXLEN)
23486 +#define MPLS_MAXNUMBERADR MPLS_ADDLISTMAXLEN / 4
23488 +/* for label mapping message */
23489 +#define MPLS_LBLMAP_MSGTYPE 0x0400 /* label mapping msg */
23490 +#define MPLS_FEC_TLVTYPE 0x0100 /* label mapping msg */
23491 +#define MPLS_GENLBL_TLVTYPE 0x0200 /* generic label tlv */
23492 +#define MPLS_ATMLBL_TLVTYPE 0x0201 /* atm label tlv */
23493 +#define MPLS_FRLBL_TLVTYPE 0x0202 /* frame relay label tlv */
23494 +#define MPLS_HOPCOUNT_TLVTYPE 0x0103 /* ho count tlv */
23495 +#define MPLS_PATH_TLVTYPE 0x0104 /* path vector tlv */
23496 +#define MPLS_REQMSGID_TLVTYPE 0x0600 /* lbl request msg id tlv */
23497 +#define MPLS_WC_FEC 0x01 /* wildcard fec element */
23498 +#define MPLS_PREFIX_FEC 0x02 /* prefix fec element */
23499 +#define MPLS_HOSTADR_FEC 0x03 /* host addr fec element */
23500 +#define MPLS_CRLSP_FEC 0x04 /* crlsp fec element */
23501 +#define MPLS_FECMAXLEN (MPLS_PDUMAXLEN - (2*MPLS_TLVFIXLEN) - \
23502 + MPLS_MSGIDFIXLEN)
23503 +#define MPLS_LBLFIXLEN 4 /* v + vpi + vci + res */
23504 +#define MPLS_HOPCOUNTFIXLEN 1 /* v + vpi + vci + res */
23505 +#define MPLS_FEC_ELEMTYPELEN 1
23506 +#define MPLS_FEC_PRELENLEN 1
23507 +#define MPLS_FEC_ADRFAMLEN 2
23508 +#define MPLS_FEC_CRLSPLEN 4 /* length of cr lsp fec */
23509 +#define MPLS_MAXHOPSNUMBER 20 /* max # hops in path vector */
23510 +#define MPLS_MAXNUMFECELEMENT 10 /* max # of fec elements */
23512 +/* for label request message */
23513 +#define MPLS_LBLREQ_MSGTYPE 0x0401 /* label request msg */
23514 +#define MPLS_LBLMSGID_TLVTYPE 0x0601 /* lbl return msg id tlv */
23515 +#define MPLS_ADR_FEC_FIXLEN (MPLS_FEC_ELEMTYPELEN + MPLS_FEC_PRELENLEN + MPLS_FEC_ADRFAMLEN)
23517 +/* for label withdraw and release messages */
23518 +#define MPLS_LBLWITH_MSGTYPE 0x0402 /* label withdraw msg */
23519 +#define MPLS_LBLREL_MSGTYPE 0x0403 /* label release msg */
23521 +/* for ER tlvs */
23522 +#define MPLS_ER_TLVTYPE 0x0800 /* constraint routing tlv */
23523 +#define MPLS_TRAFFIC_TLVTYPE 0x0810 /* traffic parameters tlv */
23524 +#define MPLS_PDR_TLVTYPE 0x0811 /* traffic peak data rate tlv */
23525 +#define MPLS_CDR_TLVTYPE 0x0812 /* committed data rate tlv */
23526 +#define MPLS_CBT_TLVTYPE 0x0813 /* committed burst tolerance */
23527 +#define MPLS_PREEMPT_TLVTYPE 0x0820 /* preemption tlv */
23528 +#define MPLS_LSPID_TLVTYPE 0x0821 /* lspid tlv */
23529 +#define MPLS_RESCLASS_TLVTYPE 0x0822 /* resource class tlv */
23530 +#define MPLS_PINNING_TLVTYPE 0x0823 /* route pinning tlv */
23531 +#define MPLS_ERHOP_IPV4_TLVTYPE 0x801 /* explicit routing ipv4 tlv */
23532 +#define MPLS_ERHOP_IPV6_TLVTYPE 0x802 /* explicit routing ipv6 tlv */
23533 +#define MPLS_ERHOP_AS_TLVTYPE 0x803 /* explicit routing autonomous
23534 + system number tlv */
23535 +#define MPLS_ERHOP_LSPID_TLVTYPE 0x804 /* explicit routing lspid tlv */
23536 +#define MPLS_ERHOP_IPV4_FIXLEN 8 /* fix length in bytes */
23537 +#define MPLS_ERHOP_IPV6_FIXLEN 20 /* fix length in bytes */
23538 +#define MPLS_ERHOP_AS_FIXLEN 4 /* fix length in bytes */
23539 +#define MPLS_ERHOP_LSPID_FIXLEN 8 /* fix length in bytes */
23540 +#define MPLS_IPV6ADRLENGTH 16
23541 +#define MPLS_MAX_ER_HOPS 20 /* decent number of hops;
23542 + change if required */
23543 +#define MPLS_PREEMPTTLV_FIXLEN 4 /* setPrio + holdPrio + res */
23544 +#define MPLS_LSPIDTLV_FIXLEN 8 /* res + crlspId + routerId */
23545 +#define MPLS_TRAFFICPARAMLENGTH 4 /* traffic parameters length */
23547 +/* for label abort request message */
23548 +#define MPLS_LBLABORT_MSGTYPE 0x0404 /* label abort request msg */
23551 + * Error codes
23552 + */
23554 +#define MPLS_ENC_BUFFTOOSMALL -1
23555 +#define MPLS_DEC_BUFFTOOSMALL -2
23556 +#define MPLS_ENC_TLVERROR -3
23557 +#define MPLS_DEC_TLVERROR -4
23558 +#define MPLS_ENC_ATMLBLERROR -5
23559 +#define MPLS_DEC_ATMLBLERROR -6
23560 +#define MPLS_ENC_BASEMSGERROR -7
23561 +#define MPLS_DEC_BASEMSGERROR -8
23562 +#define MPLS_ENC_CSPERROR -9
23563 +#define MPLS_DEC_CSPERROR -10
23564 +#define MPLS_ENC_ASPERROR -11
23565 +#define MPLS_DEC_ASPERROR -12
23566 +#define MPLS_ENC_FSPERROR -13
23567 +#define MPLS_DEC_FSPERROR -14
23568 +#define MPLS_ENC_STATUSERROR -16
23569 +#define MPLS_DEC_STATUSERROR -17
23570 +#define MPLS_ENC_EXSTATERROR -18
23571 +#define MPLS_DEC_EXSTATERROR -19
23572 +#define MPLS_ENC_RETPDUERROR -20
23573 +#define MPLS_DEC_RETPDUERROR -21
23574 +#define MPLS_ENC_RETMSGERROR -22
23575 +#define MPLS_DEC_RETMSGERROR -23
23576 +#define MPLS_PDU_LENGTH_ERROR -24
23577 +#define MPLS_ENC_CHPERROR -25
23578 +#define MPLS_DEC_CHPERROR -26
23579 +#define MPLS_ENC_CSNERROR -27
23580 +#define MPLS_DEC_CSNERROR -28
23581 +#define MPLS_ENC_TRADRERROR -29
23582 +#define MPLS_DEC_TRADRERROR -30
23583 +#define MPLS_ENC_ADRLISTERROR -31
23584 +#define MPLS_DEC_ADRLISTERROR -32
23585 +#define MPLS_WC_FECERROR -33
23586 +#define MPLS_PATHVECTORERROR -34
23587 +#define MPLS_ENC_FECERROR -35
23588 +#define MPLS_DEC_FECERROR -36
23589 +#define MPLS_ENC_GENLBLERROR -37
23590 +#define MPLS_DEC_GENLBLERROR -38
23591 +#define MPLS_ENC_MAPATMERROR -39
23592 +#define MPLS_DEC_MAPATMERROR -40
23593 +#define MPLS_ENC_FRLBLERROR -41
23594 +#define MPLS_DEC_FRLBLERROR -42
23595 +#define MPLS_ENC_COSERROR -43
23596 +#define MPLS_DEC_COSERROR -44
23597 +#define MPLS_ENC_HOPCOUNTERROR -45
23598 +#define MPLS_DEC_HOPCOUNTERROR -46
23599 +#define MPLS_ENC_PATHVECERROR -47
23600 +#define MPLS_DEC_PATHVECERROR -48
23601 +#define MPLS_ENC_LBLMSGIDERROR -49
23602 +#define MPLS_DEC_LBLMSGIDERROR -50
23603 +#define MPLS_ENC_HDRTLVERROR -51
23604 +#define MPLS_DEC_HDRTLVERROR -52
23605 +#define MPLS_ENC_FECELEMERROR -53
23606 +#define MPLS_DEC_FECELEMERROR -54
23607 +#define MPLS_ENC_FSPLBLERROR -55
23608 +#define MPLS_DEC_FSPLBLERROR -56
23609 +#define MPLS_ENC_ERHOPERROR -57
23610 +#define MPLS_DEC_ERHOPERROR -58
23611 +#define MPLS_ENC_ERTLVERROR -59
23612 +#define MPLS_DEC_ERTLVERROR -60
23613 +#define MPLS_ENC_ERHOPLENERROR -61
23614 +#define MPLS_DEC_ERHOPLENERROR -62
23615 +#define MPLS_TLVTYPEERROR -63
23616 +#define MPLS_MSGTYPEERROR -64
23617 +#define MPLS_FECERROR -65
23618 +#define MPLS_ENC_TRAFFICERROR -66
23619 +#define MPLS_DEC_TRAFFICERROR -67
23620 +#define MPLS_ENC_LSPIDERROR -68
23621 +#define MPLS_DEC_LSPIDERROR -69
23622 +#define MPLS_ENC_RESCLSERROR -70
23623 +#define MPLS_DEC_RESCLSERROR -71
23624 +#define MPLS_ENC_PREEMPTERROR -72
23625 +#define MPLS_DEC_PREEMPTERROR -73
23626 +#define MPLS_ENC_PINNINGERROR -74
23627 +#define MPLS_DEC_PINNINGERROR -75
23628 +#define MPLS_FLOATTYPEERROR -76
23629 +#define MPLS_FECTLVERROR -77
23630 +#define MPLS_IPV4LENGTHERROR -78
23631 +#define MPLS_ER_HOPSNUMERROR -79
23633 +/**********************************************************************
23634 + LDP header
23636 + 0 1 2 3
23637 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
23638 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23639 + | Version | PDU Length |
23640 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23641 + | LDP Identifier |
23642 + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23643 + | |
23644 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23645 +**********************************************************************/
23647 +typedef struct mplsLdpHeader_s {
23648 + u_short protocolVersion;
23649 + u_short pduLength; /* length excluding the version and length */
23650 + u_int lsrAddress; /* IP address assigned to LSR */
23651 + u_short labelSpace; /* within LSR */
23653 +} mplsLdpHeader_t;
23655 +/**********************************************************************
23656 + LDP Messages (All LDP messages have the following format:)
23658 + 0 1 2 3
23659 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
23660 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23661 + |U| Message Type | Message Length |
23662 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23663 + | Message ID |
23664 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23665 + | |
23666 + + +
23667 + | Mandatory Parameters |
23668 + + +
23669 + | |
23670 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23671 + | |
23672 + + +
23673 + | Optional Parameters |
23674 + + +
23675 + | |
23676 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23677 +Note: the U flag is ignored for now. There is not check for its value.
23678 +**********************************************************************/
23680 +typedef struct mplsLdpMsgFlag_s {
23681 + BITFIELDS_ASCENDING_2(u_short uBit:1, u_short msgType:15)
23682 +} mplsLdpMsgFlag_t;
23684 +typedef struct mplsLdpMsg_s {
23685 + union {
23686 + struct mplsLdpMsgFlag_s flags;
23687 + u_short mark;
23688 + } flags;
23690 + u_short msgLength; /* msgId + mandatory param + optional param */
23691 + u_int msgId; /* used to identify the notification msg */
23693 +} mplsLdpMsg_t;
23695 +typedef struct mplsLdpUnknownMsg_s {
23696 + struct mplsLdpMsg_s baseMsg;
23697 + u_char data[MPLS_NOT_MAXSIZE];
23699 +} mplsLdpUnknownMsg_t;
23701 +/**********************************************************************
23702 + Type-Length-Value Encoding
23704 + 0 1 2 3
23705 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
23706 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23707 + |U|F| Type | Length |
23708 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23709 + | |
23710 + | Value |
23711 + ~ ~
23712 + | |
23713 + | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23714 + | |
23715 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23716 +Note: the decode functions for tlv do not check the values for
23717 + F flag. They check only the value of the U flag; if
23718 + it is set will ignore the tlv and keep processing the message;
23719 + otherwise will ignore the message and return error. Please note
23720 + that the unknown tlv which is skipped will not be stored anywhere.
23721 +**********************************************************************/
23723 +typedef struct mplsLdpTlvFlag_s {
23724 + BITFIELDS_ASCENDING_3(u_short uBit:1, u_short fBit:1, u_short tBit:14)
23725 +} mplsLdpTlvFlag_t;
23727 +typedef struct mplsLdpTlv_s {
23728 + union {
23729 + struct mplsLdpTlvFlag_s flags;
23730 + u_short mark;
23731 + } flags;
23733 + u_short length; /* length of the value field */
23735 +} mplsLdpTlv_t;
23737 +/**********************************************************************
23738 + Common Session Parameters TLV
23740 + 0 1 2 3
23741 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
23742 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23743 + |U|F| Common Sess Parms (0x0500)| Length |
23744 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23745 + | Protocol Version | Keep Alive Time |
23746 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23747 + |A|D| Reserved | PVLim | Max PDU Length |
23748 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23749 + | Receiver LDP Identifer |
23750 + + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23751 + | |
23752 + -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++
23753 +***********************************************************************/
23755 +typedef struct mplsLdpCspFlag_s {
23756 + BITFIELDS_ASCENDING_4(u_short lad:1, /* 1 = downstream on demand */
23757 + u_short ld:1, /* loop detection */
23758 + u_short res:6, /* reserved */
23759 + u_short pvl:8 /* path vec limit */
23761 +} mplsLdpCspFlag_t;
23763 +typedef struct mplsLdpCspTlv_s {
23764 + struct mplsLdpTlv_s baseTlv;
23765 + u_short protocolVersion;
23766 + u_short holdTime; /* proposed keep alive interval */
23768 + union {
23769 + struct mplsLdpCspFlag_s flags;
23770 + u_short mark;
23771 + } flags;
23773 + u_short maxPduLen;
23774 + u_int rcvLsrAddress;
23775 + u_short rcvLsId;
23777 +} mplsLdpCspTlv_t;
23779 +/***********************************************************************
23780 + ATM Label Range Component
23782 + 0 1 2 3
23783 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
23784 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23785 + | Res | Minimum VPI | Minimum VCI |
23786 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23787 + | Res | Maximum VPI | Maximum VCI |
23788 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23789 +***********************************************************************/
23791 +typedef struct mplsLdpAtmLblRngFlag_s {
23792 + BITFIELDS_ASCENDING_3(u_int res1:4, /* reserved : 0 on transmision */
23793 + u_int minVpi:12, /* if <12 bits right justified */
23794 + u_int minVci:16 /* if <16 bits right justified */
23796 + BITFIELDS_ASCENDING_3(u_int res2:4, /* reserved : 0 on transmision */
23797 + u_int maxVpi:12, /* if <12 bits right justified */
23798 + u_int maxVci:16 /* if <16 bits right justified */
23800 +} mplsLdpAtmLblRngFlag_t;
23802 +typedef struct mplsLdpAtmLblRng_s {
23803 + union {
23804 + struct mplsLdpAtmLblRngFlag_s flags;
23805 + u_int mark[2];
23806 + } flags;
23807 +} mplsLdpAtmLblRng_t;
23809 +/***********************************************************************
23810 + Flags for ATM Session Parameters TLV and
23811 + Frame Relay Session Parameters TLV
23813 + Note: both types of session parameters have the same type of flags;
23814 + use then the same struct
23815 +***********************************************************************/
23817 +typedef struct mplsLdpSPFlag_s {
23818 + BITFIELDS_ASCENDING_4(u_int mergeType:2, /* merge typ */
23819 + u_int numLblRng:4, /* # of label range com */
23820 + u_int dir:1, /* 0 => bidirectional */
23821 + u_int res:25)
23822 +} mplsLdpSPFlag_t;
23824 +/***********************************************************************
23825 + ATM Session Parameters TLV
23827 + 0 1 2 3
23828 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
23829 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23830 + |U|F| ATM Sess Parms (0x0501) | Length |
23831 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23832 + | M | N |D| Reserved |
23833 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23834 + | ATM Label Range Component 1 |
23835 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23836 + | |
23837 + ~ ~
23838 + | |
23839 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23840 + | ATM Label Range Component N |
23841 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23842 +***********************************************************************/
23844 +typedef struct mplsLdpAspTlv_s {
23845 + struct mplsLdpTlv_s baseTlv;
23846 + union {
23847 + struct mplsLdpSPFlag_s flags;
23848 + u_int mark;
23849 + } flags;
23850 + struct mplsLdpAtmLblRng_s lblRngList[MPLS_ATMLBLMAXLEN];
23852 +} mplsLdpAspTlv_t;
23854 +/***********************************************************************
23855 + Frame Relay Label Range Component
23857 + 0 1 2 3
23858 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
23859 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23860 + | Reserved |Len| Minimum DLCI |
23861 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23862 + | Reserved | Maximum DLCI |
23863 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23864 +***********************************************************************/
23866 +typedef struct mplsLdpFrFlag_s {
23867 + BITFIELDS_ASCENDING_3(u_int res_min:7, u_int len:2, u_int minDlci:23)
23868 + BITFIELDS_ASCENDING_2(u_int res_max:9, u_int maxDlci:23)
23869 +} mplsLdpFrFlag_t;
23871 +typedef struct mplsLdpFrLblRng_s {
23872 + union {
23873 + struct mplsLdpFrFlag_s flags;
23874 + u_int mark[2];
23875 + } flags;
23877 +} mplsLdpFrLblRng_t;
23879 +/**********************************************************************
23880 + Frame Relay Session Parameters TLV
23882 + 0 1 2 3
23883 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
23884 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23885 + |U|F| FR Sess Parms (0x0502) | Length |
23886 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23887 + | M | N |D| Reserved |
23888 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23889 + | Frame Relay Label Range Component 1 |
23890 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23891 + | |
23892 + ~ ~
23893 + | |
23894 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23895 + | Frame Relay Label Range Component N |
23896 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23897 +***********************************************************************/
23899 +typedef struct mplsLdpFspTlv_s {
23900 + struct mplsLdpTlv_s baseTlv;
23901 + union {
23902 + struct mplsLdpSPFlag_s flags;
23903 + u_int mark;
23904 + } flags;
23905 + struct mplsLdpFrLblRng_s lblRngList[MPLS_FRLBLMAXLEN];
23907 +} mplsLdpFspTlv_t;
23909 +/***********************************************************************
23910 + Initialization Message Encoding
23912 + 0 1 2 3
23913 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
23914 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23915 + |U| Initialization (0x0200) | Message Length |
23916 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23917 + | Message ID |
23918 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23919 + | Common Session Parameters TLV |
23920 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23921 + | Optional Parameters |
23922 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23923 +***********************************************************************/
23925 +typedef struct mplsLdpInitMsg_s {
23926 + struct mplsLdpMsg_s baseMsg;
23927 + struct mplsLdpCspTlv_s csp;
23928 + struct mplsLdpAspTlv_s asp;
23929 + struct mplsLdpFspTlv_s fsp;
23930 + u_char cspExists:1;
23931 + u_char aspExists:1;
23932 + u_char fspExists:1;
23934 +} mplsLdpInitMsg_t;
23936 +/***********************************************************************
23937 + Status Code Encoding
23939 + 0 1 2 3
23940 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
23941 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23942 + |E|F| Status Data |
23943 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23944 +***********************************************************************/
23945 +typedef struct mplsLdpStautsFlag_s {
23946 + BITFIELDS_ASCENDING_3(u_int error:1, /* E bit */
23947 + u_int forward:1, /* F bit */
23948 + u_int status:30)
23949 +} mplsLdpStautsFlag_t;
23951 +/***********************************************************************
23952 + Status (TLV) Encoding
23954 + 0 1 2 3
23955 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
23956 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23957 + |U|F| Status (0x0300) | Length |
23958 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23959 + | Status Code |
23960 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23961 + | Message ID |
23962 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23963 + | Message Type |
23964 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23965 +***********************************************************************/
23967 +typedef struct mplsLdpStatusTlv_s {
23968 + struct mplsLdpTlv_s baseTlv;
23969 + union {
23970 + struct mplsLdpStautsFlag_s flags;
23971 + u_int mark;
23972 + } flags;
23973 + u_int msgId;
23974 + u_short msgType;
23976 +} mplsLdpStatusTlv_t;
23978 +/***********************************************************************
23979 + Extended Status (TLV) Encoding
23980 +***********************************************************************/
23982 +typedef struct mplsLdpExStatusTlv_s {
23983 + struct mplsLdpTlv_s baseTlv;
23984 + u_int value; /* additional info for status */
23986 +} mplsLdpExStatusTlv_t;
23988 +/***********************************************************************
23989 + Returned PDU (TLV) Encoding
23990 +***********************************************************************/
23992 +typedef struct mplsLdpRetPduTlv_s {
23993 + struct mplsLdpTlv_s baseTlv;
23994 + struct mplsLdpHeader_s headerTlv;
23995 + u_char data[MPLS_NOT_MAXSIZE];
23997 +} mplsLdpRetPduTlv_t;
23999 +/***********************************************************************
24000 + Returned MSG (TLV) Encoding
24001 +***********************************************************************/
24003 +typedef struct mplsLdpRetMsgTlv_s {
24004 + struct mplsLdpTlv_s baseTlv;
24005 + u_short msgType;
24006 + u_short msgLength;
24007 + u_char data[MPLS_NOT_MAXSIZE];
24009 +} mplsLdpRetMsgTlv_t;
24011 +/***********************************************************************
24012 + LSPID Tlv encoding
24014 + 0 1 2 3
24015 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24016 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24017 + |U|F| LSPID-TLV (0x0821) | Length |
24018 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24019 + | Reserved | Local CRLSP ID |
24020 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24021 + | Ingress LSR Router ID |
24022 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24023 +***********************************************************************/
24025 +typedef struct mplsLdpLspIdTlv_s {
24026 + struct mplsLdpTlv_s baseTlv;
24027 + u_short res;
24028 + u_short localCrlspId;
24029 + u_int routerId; /* ingress lsr router id */
24031 +} mplsLdpLspIdTlv_t;
24033 +/***********************************************************************
24034 + Notification Message Encoding
24036 + 0 1 2 3
24037 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24038 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24039 + |U| Notification (0x0001) | Message Length |
24040 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24041 + | Message ID |
24042 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24043 + | Status (TLV) |
24044 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24045 + | Optional Parameters |
24046 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24047 + | LSPID TLV (optional for CR-LDP) |
24048 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24049 +***********************************************************************/
24051 +typedef struct mplsLdpNotifMsg_s {
24052 + struct mplsLdpMsg_s baseMsg;
24053 + struct mplsLdpStatusTlv_s status;
24054 + struct mplsLdpExStatusTlv_s exStatus; /* extended status tlv */
24055 + struct mplsLdpRetPduTlv_s retPdu; /* returned PDU tlv */
24056 + struct mplsLdpRetMsgTlv_s retMsg; /* returned MSG tlv */
24057 + struct mplsLdpLspIdTlv_s lspidTlv; /* lspid tlv */
24059 + u_char statusTlvExists:1;
24060 + u_char exStatusTlvExists:1;
24061 + u_char retPduTlvExists:1;
24062 + u_char retMsgTlvExists:1;
24063 + u_char lspidTlvExists:1;
24065 +} mplsLdpNotifMsg_t;
24067 +/***********************************************************************
24068 + Common Hello Parameters Tlv encoding
24070 + 0 1 2 3
24071 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24072 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24073 + |U|F| Common Hello Parms(0x0400)| Length |
24074 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24075 + | Hold Time |T|R| Reserved |
24076 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24077 +***********************************************************************/
24078 +typedef struct mplsLdpChpFlag_s {
24079 + BITFIELDS_ASCENDING_3(u_short target:1, /* T bit */
24080 + u_short request:1, /* R bit */
24081 + u_short res:14)
24082 +} mplsLdpChpFlag_t;
24084 +typedef struct mplsLdpChpTlv_s {
24085 + struct mplsLdpTlv_s baseTlv;
24086 + u_short holdTime;
24087 + union {
24088 + struct mplsLdpChpFlag_s flags;
24089 + u_short mark;
24090 + } flags;
24092 +} mplsLdpChpTlv_t;
24094 +/***********************************************************************
24095 + Transport Address (TLV) Encoding
24096 +***********************************************************************/
24098 +typedef struct mplsLdpTrAdrTlv_s {
24099 + struct mplsLdpTlv_s baseTlv;
24100 + u_int address;
24102 +} mplsLdpTrAdrTlv_t;
24104 +/***********************************************************************
24105 + Configuration Sequence Number (TLV) Encoding
24106 +***********************************************************************/
24108 +typedef struct mplsLdpCsnTlv_s {
24109 + struct mplsLdpTlv_s baseTlv;
24110 + u_int seqNumber;
24112 +} mplsLdpCsnTlv_t;
24114 +/***********************************************************************
24115 + Hello message encoding
24117 + 0 1 2 3
24118 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24119 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24120 + |U| Hello (0x0100) | Message Length |
24121 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24122 + | Message ID |
24123 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24124 + | Common Hello Parameters TLV |
24125 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24126 + | Optional Parameters |
24127 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24128 +***********************************************************************/
24130 +typedef struct mplsLdpHelloMsg_s {
24131 + struct mplsLdpMsg_s baseMsg;
24132 + struct mplsLdpChpTlv_s chp; /* common hello param tlv */
24133 + struct mplsLdpTrAdrTlv_s trAdr; /* transport address tlv */
24134 + struct mplsLdpCsnTlv_s csn; /* configuration seq # tlv */
24135 + u_char chpTlvExists:1;
24136 + u_char trAdrTlvExists:1;
24137 + u_char csnTlvExists:1;
24139 +} mplsLdpHelloMsg_t;
24141 +/***********************************************************************
24142 + KeepAlive Message encoding
24144 + 0 1 2 3
24145 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24146 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24147 + |U| KeepAlive (0x0201) | Message Length |
24148 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24149 + | Message ID |
24150 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24151 + | Optional Parameters |
24152 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24154 +Note: there are no optional param defined for keep alive.
24155 +***********************************************************************/
24157 +typedef struct mplsLdpKeepAlMsg_s {
24158 + struct mplsLdpMsg_s baseMsg;
24160 +} mplsLdpKeepAlMsg_t;
24162 +/***********************************************************************
24163 + Address List TLV encoding
24165 + 0 1 2 3
24166 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24167 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24168 + |U|F| Address List (0x0101) | Length |
24169 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24170 + | Address Family | |
24171 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
24172 + | |
24173 + | Addresses |
24174 + ~ ~
24175 + | |
24176 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24177 +***********************************************************************/
24179 +typedef struct mplsLdpAdrTlv_s {
24180 + struct mplsLdpTlv_s baseTlv;
24181 + u_short addrFamily;
24182 + u_int address[MPLS_MAXNUMBERADR];
24184 +} mplsLdpAdrTlv_t;
24186 +/***********************************************************************
24187 + Address (0x0300) / Address Withdraw(0x0301) message encoding
24189 + 0 1 2 3
24190 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24191 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24192 + |U| Address | Message Length |
24193 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24194 + | Message ID |
24195 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24196 + | |
24197 + | Address List TLV |
24198 + | |
24199 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24200 + | Optional Parameters |
24201 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24203 +Note: there are no optional param defined for address message.
24204 +***********************************************************************/
24206 +typedef struct mplsLdpAdrMsg_s {
24207 + struct mplsLdpMsg_s baseMsg;
24208 + struct mplsLdpAdrTlv_s addressList;
24209 + u_char adrListTlvExists:1;
24211 +} mplsLdpAdrMsg_t;
24213 +/***********************************************************************
24214 + Wildcard FEC Element encoding
24215 +***********************************************************************/
24217 +typedef struct mplsLdpWildFec_s {
24218 + u_char type;
24220 +} mplsLdpWildFec_t;
24222 +/***********************************************************************
24223 + Prefix FEC Element encoding
24225 + 0 1 2 3
24226 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24227 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24228 + | Prefix (2) | Address Family | PreLen |
24229 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24230 + | Prefix |
24231 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24233 + Host Address FEC Element encoding
24235 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24236 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24237 + | Host Addr (3) | Address Family | Host Addr Len |
24238 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24239 + | Host Addr |
24240 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24242 +Note: the code handles prefixes and host addresses whose length is
24243 + less or equal to 4 bytes.
24244 +***********************************************************************/
24246 +typedef struct mplsLdpAddressFec_s {
24247 + u_char type;
24248 + u_short addressFam;
24249 + u_char preLen; /* prefix FEC: length of the adr prefix (in bits)
24250 + or host adr FEC: length of the host address (in
24251 + bytes) */
24252 + u_int address;
24254 +} mplsLdpAddressFec_t;
24256 +/***********************************************************************
24257 + CRLSP FEC Element encoding
24259 + 0 1 2 3
24260 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24261 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24262 + | CR-LSP (4) | Reserved |
24263 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24264 +***********************************************************************/
24266 +typedef struct mplsLdpCrlspFec_s {
24267 + u_char type;
24268 + u_char res1; /* reserved */
24269 + u_short res2; /* reserved */
24271 +} mplsLdpCrlspFec_t;
24273 +/***********************************************************************
24274 + FEC Tlv encoding
24276 + 0 1 2 3
24277 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24278 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24279 + |U|F| FEC (0x0100) | Length |
24280 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24281 + | FEC Element 1 |
24282 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24283 + | |
24284 + ~ ~
24285 + | |
24286 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24287 + | FEC Element n |
24288 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24289 +***********************************************************************/
24291 +typedef union mplsFecElement_u {
24292 + struct mplsLdpAddressFec_s addressEl; /* prefix | host adr */
24293 + struct mplsLdpWildFec_s wildcardEl; /* for wilcard fec */
24294 + struct mplsLdpCrlspFec_s crlspEl; /* CRLSP fec elem */
24296 +} mplsFecElement_t;
24298 +typedef struct mplsLdpFecTlv_s {
24299 + struct mplsLdpTlv_s baseTlv;
24300 + union mplsFecElement_u fecElArray[MPLS_MAXNUMFECELEMENT];
24301 + u_short fecElemTypes[MPLS_MAXNUMFECELEMENT];
24302 + u_char wcElemExists:1;
24303 + u_short numberFecElements;
24305 +} mplsLdpFecTlv_t;
24307 +/***********************************************************************
24308 + Generic Label Tlv encoding
24310 + 0 1 2 3
24311 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24312 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24313 + |U|F| Generic Label (0x0200) | Length |
24314 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24315 + | Label |
24316 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24317 +***********************************************************************/
24319 +typedef struct mplsLdpGenLblTlv_s {
24320 + struct mplsLdpTlv_s baseTlv;
24321 + u_int label; /* 20-bit number in 4 octet field */
24323 +} mplsLdpGenLblTlv_t;
24325 +/***********************************************************************
24326 + Atm Label Tlv encoding
24328 + 0 1 2 3
24329 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24330 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24331 + |U|F| ATM Label (0x0201) | Length |
24332 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24333 + |Res| V | VPI | VCI |
24334 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24335 +***********************************************************************/
24337 +typedef struct mplsLdpAtmLblFlag_s {
24338 + BITFIELDS_ASCENDING_3(u_short res:2, u_short v:2, u_short vpi:12)
24339 +} mplsLdpAtmLblFlag_t;
24341 +typedef struct mplsLdpAtmLblTlv_s {
24342 + struct mplsLdpTlv_s baseTlv;
24344 + union {
24345 + struct mplsLdpAtmLblFlag_s flags;
24346 + u_short mark;
24347 + } flags;
24349 + u_short vci;
24351 +} mplsLdpAtmLblTlv_t;
24353 +/***********************************************************************
24354 + Frame Relay Label Tlv encoding
24356 + 0 1 2 3
24357 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24358 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24359 + |U|F| Frame Relay Label (0x0202)| Length |
24360 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24361 + | Reserved |Len| DLCI |
24362 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24363 +***********************************************************************/
24365 +typedef struct mplsLdpFrLblFlag_s {
24366 + BITFIELDS_ASCENDING_3(u_int res:7, u_int len:2, u_int dlci:23)
24368 +} mplsLdpFrLblFlag_t;
24370 +typedef struct mplsLdpFrLblTlv_s {
24371 + struct mplsLdpTlv_s baseTlv;
24373 + union {
24374 + struct mplsLdpFrLblFlag_s flags;
24375 + u_int mark;
24376 + } flags;
24378 +} mplsLdpFrLblTlv_t;
24380 +/***********************************************************************
24381 + Hop Count Tlv encoding
24383 + 0 1 2 3
24384 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24385 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24386 + |U|F| Hop Count (0x0103) | Length |
24387 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24388 + | HC Value |
24389 + +-+-+-+-+-+-+-+-+
24390 +***********************************************************************/
24392 +typedef struct mplsLdpHopTlv_s {
24393 + struct mplsLdpTlv_s baseTlv;
24394 + u_char hcValue; /* hop count value */
24396 +} mplsLdpHopTlv_t;
24398 +/***********************************************************************
24399 + Path Vector Tlv encoding
24401 + 0 1 2 3
24402 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24403 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24404 + |U|F| Path Vector (0x0104) | Length |
24405 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24406 + | LSR Id 1 |
24407 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24408 + | |
24409 + ~ ~
24410 + | |
24411 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24412 + | LSR Id n |
24413 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24414 +***********************************************************************/
24416 +typedef struct mplsLdpPathTlv_s {
24417 + struct mplsLdpTlv_s baseTlv;
24418 + u_int lsrId[MPLS_MAXHOPSNUMBER];
24420 +} mplsLdpPathTlv_t;
24422 +/***********************************************************************
24423 + Lbl request message id Tlv encoding
24424 +***********************************************************************/
24426 +typedef struct mplsLdpLblMsgIdTlv_s {
24427 + struct mplsLdpTlv_s baseTlv;
24428 + u_int msgId;
24430 +} mplsLdpLblMsgIdTlv_t;
24432 +/***********************************************************************
24433 + Preemption Tlv encoding
24435 + 0 1 2 3
24436 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24437 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24438 + |U|F| Preemption-TLV (0x0820) | Length |
24439 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24440 + | SetPrio | HoldPrio | Reserved |
24441 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24442 +***********************************************************************/
24444 +typedef struct mplsLdpPreemptTlv_s {
24445 + struct mplsLdpTlv_s baseTlv;
24446 + u_char setPrio; /* 0 => most important path */
24447 + u_char holdPrio; /* 0 => most important path */
24448 + u_short res;
24450 +} mplsLdpPreemptTlv_t;
24452 +/***********************************************************************
24453 + Resource class Tlv encoding
24455 + 0 1 2 3
24456 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24457 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24458 + |U|F| ResCls-TLV (0x0822) | Length |
24459 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24460 + | RsCls |
24461 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24462 +***********************************************************************/
24464 +typedef struct mplsLdpResClsTlv_s {
24465 + struct mplsLdpTlv_s baseTlv;
24466 + u_int rsCls; /* resource class bit mask */
24468 +} mplsLdpResClsTlv_t;
24470 +/***********************************************************************
24471 + Lbl return message id Tlv encoding
24472 +***********************************************************************/
24474 +typedef struct mplsLdpRetMsgIdTlv_s {
24475 + struct mplsLdpTlv_s baseTlv;
24477 +} mplsLdpLblRetMsgIdTlv_t;
24479 +/***********************************************************************
24480 + ER flag structure which is common to IPV4 and IPV6 ER TLV
24481 +***********************************************************************/
24483 +typedef struct mplsLdpErIPFlag_s {
24484 + BITFIELDS_ASCENDING_3(u_int l:1, /* 0 => loose hop */
24485 + u_int res:23, u_int preLen:8)
24486 +} mplsLdpErIPFlag_t;
24488 +/***********************************************************************
24489 + ER flag structure which is common to AS and LSPID ER TLV
24490 +***********************************************************************/
24491 +typedef struct mplsLdpErFlag_s {
24492 + BITFIELDS_ASCENDING_2(u_short l:1, /* 0 => loose hop */
24493 + u_short res:15)
24494 +} mplsLdpErFlag_t;
24496 +/***********************************************************************
24497 + Explicit Routing IPv4 Tlv encoding
24499 + 0 1 2 3
24500 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24501 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24502 + |U|F| 0x801 | Length |
24503 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24504 + |L| Reserved | PreLen |
24505 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24506 + | IPv4 Address (4 bytes) |
24507 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24508 +***********************************************************************/
24510 +typedef struct mplsLdpErIpv4_s {
24511 + struct mplsLdpTlv_s baseTlv;
24512 + union {
24513 + struct mplsLdpErIPFlag_s flags;
24514 + u_int mark;
24515 + } flags;
24516 + u_int address;
24518 +} mplsLdpErIpv4_t;
24520 +/***********************************************************************
24521 + Explicit Routing IPv6 Tlv encoding
24523 + 0 1 2 3
24524 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24525 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24526 + |U|F| 0x802 | Length |
24527 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24528 + |L| Reserved | PreLen |
24529 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24530 + | IPV6 address |
24531 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24532 + | IPV6 address (continued) |
24533 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24534 + | IPV6 address (continued) |
24535 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24536 + | IPV6 address (continued) |
24537 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24538 +***********************************************************************/
24540 +typedef struct mplsLdpErIpv6_s {
24541 + struct mplsLdpTlv_s baseTlv;
24542 + union {
24543 + struct mplsLdpErIPFlag_s flags;
24544 + u_int mark;
24545 + } flags;
24546 + u_char address[MPLS_IPV6ADRLENGTH];
24548 +} mplsLdpErIpv6_t;
24550 +/***********************************************************************
24551 + Explicit Routing Autonomous systen number Tlv encoding
24553 + 0 1 2 3
24554 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24555 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24556 + |U|F| 0x803 | Length |
24557 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24558 + |L| Reserved | AS Number |
24559 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24560 +***********************************************************************/
24562 +typedef struct mplsLdpErAs_s {
24563 + struct mplsLdpTlv_s baseTlv;
24564 + union {
24565 + struct mplsLdpErFlag_s flags;
24566 + u_short mark;
24567 + } flags;
24568 + u_short asNumber;
24570 +} mplsLdpErAs_t;
24572 +/***********************************************************************
24573 + Explicit Routing LSPID Tlv encoding
24575 + 0 1 2 3
24576 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24577 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24578 + |U|F| 0x804 | Length |
24579 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24580 + |L| Reserved | Local LSPID |
24581 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24582 + | Ingress LSR Router ID |
24583 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24584 +***********************************************************************/
24586 +typedef struct mplsLdpErLspId_s {
24587 + struct mplsLdpTlv_s baseTlv;
24588 + union {
24589 + struct mplsLdpErFlag_s flags;
24590 + u_short mark;
24591 + } flags;
24592 + u_short lspid;
24593 + u_int routerId;
24595 +} mplsLdpErLspId_t;
24597 +/***********************************************************************
24598 + Constraint Routing Tlv encoding
24600 + 0 1 2 3
24601 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24602 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24603 + |U|F| ER-TLV (0x0800) | Length |
24604 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24605 + | ER-Hop TLV 1 |
24606 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24607 + | ER-Hop TLV 2 |
24608 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24609 + ~ ............ ~
24610 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24611 + | ER-Hop TLV n |
24612 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24613 +***********************************************************************/
24615 +typedef union mplsLdpErHop_u {
24616 + struct mplsLdpErIpv4_s erIpv4;
24617 + struct mplsLdpErIpv6_s erIpv6;
24618 + struct mplsLdpErAs_s erAs;
24619 + struct mplsLdpErLspId_s erLspId;
24621 +} mplsLdpErHop_t;
24623 +typedef struct mplsLdpErTlv_s {
24624 + struct mplsLdpTlv_s baseTlv;
24625 + union mplsLdpErHop_u erHopArray[MPLS_MAX_ER_HOPS];
24626 + u_short erHopTypes[MPLS_MAX_ER_HOPS]; /* need to know the
24627 + types when handle
24628 + the union */
24629 + u_short numberErHops;
24631 +} mplsLdpErTlv_t;
24633 +/***********************************************************************
24634 + Traffic parameters TLV
24636 + 0 1 2 3
24637 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24638 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24639 + |U|F| Traf. Param. TLV (0x0810)| Length |
24640 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24641 + | Flags | Frequency | Reserved | Weight |
24642 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24643 + | Peak Data Rate (PDR) |
24644 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24645 + | Peak Burst Size (PBS) |
24646 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24647 + | Committed Data Rate (CDR) |
24648 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24649 + | Committed Burst Size (CBS) |
24650 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24651 + | Excess Burst Size (EBS) |
24652 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24654 + Flag field:
24655 + +--+--+--+--+--+--+--+--+
24656 + | Res |F6|F5|F4|F3|F2|F1|
24657 + +--+--+--+--+--+--+--+--+
24658 +***********************************************************************/
24660 +typedef struct mplsLdpTrafficFlag_s {
24661 + BITFIELDS_ASCENDING_7(u_char res:2,
24662 + u_char f6Bit:1,
24663 + u_char f5Bit:1,
24664 + u_char f4Bit:1, u_char f3Bit:1, u_char f2Bit:1, u_char f1Bit:1)
24665 +} mplsLdpTrafficFlag_t;
24667 +typedef struct mplsLdpTrafficTlv_s {
24668 + struct mplsLdpTlv_s baseTlv;
24669 + union {
24670 + struct mplsLdpTrafficFlag_s flags;
24671 + u_char mark;
24672 + } flags;
24673 + u_char freq;
24674 + u_char res;
24675 + u_char weight;
24676 + union {
24677 + float pdr;
24678 + u_int mark;
24679 + } pdr;
24680 + union {
24681 + float pbs;
24682 + u_int mark;
24683 + } pbs;
24684 + union {
24685 + float cdr;
24686 + u_int mark;
24687 + } cdr;
24688 + union {
24689 + float cbs;
24690 + u_int mark;
24691 + } cbs;
24692 + union {
24693 + float ebs;
24694 + u_int mark;
24695 + } ebs;
24697 +} mplsLdpTrafficTlv_t;
24699 +/***********************************************************************
24700 + Route pinning TLV
24702 + 0 1 2 3
24703 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24704 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24705 + |U|F| 0x823 | Length |
24706 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24707 + |P| Reserved |
24708 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24709 +***********************************************************************/
24711 +typedef struct mplsLdpPinningTlvFlag_s {
24712 + BITFIELDS_ASCENDING_2(u_int pBit:1, /* 1 => route pinning requested */
24713 + u_int res:31)
24714 +} mplsLdpPinningTlvFlag_t;
24716 +typedef struct mplsLdpPinningTlv_s {
24717 + struct mplsLdpTlv_s baseTlv;
24718 + union {
24719 + struct mplsLdpPinningTlvFlag_s flags;
24720 + u_int mark;
24721 + } flags;
24722 +} mplsLdpPinningTlv_t;
24724 +/***********************************************************************
24725 + Label Mapping Message encoding
24727 + 0 1 2 3
24728 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24729 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24730 + |U| Label Mapping (0x0400) | Message Length |
24731 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24732 + | Message ID |
24733 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24734 + | FEC TLV |
24735 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24736 + | Label TLV |
24737 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24738 + | Label Request Message ID TLV (mandatory) |
24739 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24740 + | LSPID TLV (CR-LDP, mandatory) |
24741 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24742 + | Traffic TLV (CR-LDP, optional) |
24743 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24744 +***********************************************************************/
24746 +typedef struct mplsLdpLblMapMsg_s {
24747 + struct mplsLdpMsg_s baseMsg;
24749 + /* FEC tlv */
24750 + struct mplsLdpFecTlv_s fecTlv;
24752 + /* Label TLV */
24753 + struct mplsLdpGenLblTlv_s genLblTlv; /* generic label tlv */
24754 + struct mplsLdpAtmLblTlv_s atmLblTlv; /* atm label tlv */
24755 + struct mplsLdpFrLblTlv_s frLblTlv; /* fr label tlv */
24757 + /* Optional parameters */
24758 + struct mplsLdpHopTlv_s hopCountTlv; /* hop count tlv */
24759 + struct mplsLdpPathTlv_s pathVecTlv; /* path vector tlv */
24760 + struct mplsLdpLblMsgIdTlv_s lblMsgIdTlv; /* lbl msg id tlv */
24761 + struct mplsLdpLspIdTlv_s lspidTlv; /* lspid tlv */
24762 + struct mplsLdpTrafficTlv_s trafficTlv; /* traffic tlv */
24764 + u_char fecTlvExists:1;
24765 + u_char genLblTlvExists:1;
24766 + u_char atmLblTlvExists:1;
24767 + u_char frLblTlvExists:1;
24768 + u_char hopCountTlvExists:1;
24769 + u_char pathVecTlvExists:1;
24770 + u_char lblMsgIdTlvExists:1;
24771 + u_char lspidTlvExists:1;
24772 + u_char trafficTlvExists:1;
24774 +} mplsLdpLblMapMsg_t;
24776 +/***********************************************************************
24777 + Label Request Message encoding
24779 + 0 1 2 3
24780 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24781 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24782 + |U| Label Request (0x0401) | Message Length |
24783 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24784 + | Message ID |
24785 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24786 + | FEC TLV |
24787 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24788 + | Return Message ID TLV (mandatory) |
24789 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24790 + | LSPID TLV (CR-LDP, mandatory) |
24791 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24792 + | ER-TLV (CR-LDP, optional) |
24793 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24794 + | Traffic TLV (CR-LDP, optional) |
24795 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24796 + | Pinning TLV (CR-LDP, optional) |
24797 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24798 + | Resource Class TLV (CR-LDP, optional) |
24799 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24800 + | Pre-emption TLV (CR-LDP, optional) |
24801 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24802 +***********************************************************************/
24804 +typedef struct mplsLdpLblReqMsg_s {
24805 + struct mplsLdpMsg_s baseMsg;
24807 + /* FEC tlv */
24808 + struct mplsLdpFecTlv_s fecTlv;
24810 + /* Optional parameters */
24811 + struct mplsLdpHopTlv_s hopCountTlv; /* hop count tlv */
24812 + struct mplsLdpPathTlv_s pathVecTlv; /* path vector tlv */
24814 + /* Optional parameters for CR */
24815 + struct mplsLdpRetMsgIdTlv_s lblMsgIdTlv; /* lbl msg id tlv */
24816 + struct mplsLdpErTlv_s erTlv; /* constraint rtg tlv */
24817 + struct mplsLdpTrafficTlv_s trafficTlv; /* traffic tlv */
24818 + struct mplsLdpLspIdTlv_s lspidTlv; /* lspid tlv */
24819 + struct mplsLdpPinningTlv_s pinningTlv; /* pinning tlv */
24820 + struct mplsLdpResClsTlv_s resClassTlv; /* resource class tlv */
24821 + struct mplsLdpPreemptTlv_s preemptTlv; /* peemtion tlv */
24823 + u_char fecTlvExists:1;
24824 + u_char hopCountTlvExists:1;
24825 + u_char pathVecTlvExists:1;
24826 + u_char lblMsgIdTlvExists:1;
24827 + u_char erTlvExists:1;
24828 + u_char trafficTlvExists:1;
24829 + u_char lspidTlvExists:1;
24830 + u_char pinningTlvExists:1;
24831 + u_char recClassTlvExists:1;
24832 + u_char preemptTlvExists:1;
24834 +} mplsLdpLblReqMsg_t;
24836 +/***********************************************************************
24838 + Label Withdraw Message encoding
24840 + 0 1 2 3
24841 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24842 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24843 + |U| Label Withdraw (0x0402) | Message Length |
24844 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24845 + | Message ID |
24846 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24847 + | FEC TLV |
24848 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24849 + | Label TLV (optional) |
24850 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24851 + | LSPID TLV (optional for CR-LDP) |
24852 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24854 + Label Release Message encoding
24856 + 0 1 2 3
24857 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24858 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24859 + |U| Label Release (0x0403) | Message Length |
24860 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24861 + | Message ID |
24862 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24863 + | FEC TLV |
24864 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24865 + | Label TLV (optional) |
24866 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24867 + | LSPID TLV (optional for CR-LDP) |
24868 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24870 +Note: the Label Withdraw Message encoding and the Label Release Message enc
24871 + look very much the same. I will create only one type of struct for
24872 + both message types.
24873 + The Label Withdraw Message and Label Release Message can optionally
24874 + carry LSPID TLV.
24875 +***********************************************************************/
24877 +typedef struct mplsLdpLbl_W_R_Msg_s {
24878 + struct mplsLdpMsg_s baseMsg;
24880 + /* FEC tlv */
24881 + struct mplsLdpFecTlv_s fecTlv;
24883 + /* Label TLV */
24884 + struct mplsLdpGenLblTlv_s genLblTlv; /* generic label tlv */
24885 + struct mplsLdpAtmLblTlv_s atmLblTlv; /* atm label tlv */
24886 + struct mplsLdpFrLblTlv_s frLblTlv; /* fr label tlv */
24887 + struct mplsLdpLspIdTlv_s lspidTlv; /* lspid tlv */
24889 + u_char fecTlvExists:1;
24890 + u_char genLblTlvExists:1;
24891 + u_char atmLblTlvExists:1;
24892 + u_char frLblTlvExists:1;
24893 + u_char lspidTlvExists:1;
24895 +} mplsLdpLbl_W_R_Msg_t;
24897 +/***********************************************************************
24898 + Label Abort Request Message encoding
24900 + 0 1 2 3
24901 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24902 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24903 + |U| Label Abort Req (0x0404) | Message Length |
24904 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24905 + | Message ID |
24906 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24907 + | FEC TLV |
24908 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24909 + | Label Request Message ID TLV |
24910 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24911 +***********************************************************************/
24913 +typedef struct mplsLdpLblAbortMsg_s {
24914 + struct mplsLdpMsg_s baseMsg;
24916 + struct mplsLdpFecTlv_s fecTlv; /* fec tlv */
24917 + struct mplsLdpLblMsgIdTlv_s lblMsgIdTlv; /* lbl msg id tlv */
24919 + u_char fecTlvExists:1;
24920 + u_char lblMsgIdTlvExists:1;
24922 +} mplsLdpLblAbortMsg_t;
24924 +/***********************************************************************
24926 + * Function declarations
24928 + * Note: Encode functions return the length of the data which was encoded.
24929 + * The first argument (which is a pointer to the structure which
24930 + * contains the data to be encoded) is not modified in the encode functions
24931 + * which encode the messages and message headers. All the other encode
24932 + * fuctions modify the content of the structures to be encoded (tlvs,
24933 + * message parameters, etc).
24935 + * Decode functions for tlv return the length of the value.
24936 + */
24938 +int Mpls_encodeLdpMsgHeader(mplsLdpHeader_t *, u_char *, int);
24939 +int Mpls_decodeLdpMsgHeader(mplsLdpHeader_t *, u_char *, int);
24940 +int Mpls_encodeLdpAtmLblRng(mplsLdpAtmLblRng_t *, u_char *, int);
24941 +int Mpls_decodeLdpAtmLblRng(mplsLdpAtmLblRng_t *, u_char *, int);
24942 +int Mpls_encodeLdpAsp(mplsLdpAspTlv_t *, u_char *, int);
24943 +int Mpls_decodeLdpAsp(mplsLdpAspTlv_t *, u_char *, int);
24944 +int Mpls_encodeLdpTlv(mplsLdpTlv_t *, u_char *, int);
24945 +int Mpls_decodeLdpTlv(mplsLdpTlv_t *, u_char *, int);
24946 +int Mpls_encodeLdpInitMsg(mplsLdpInitMsg_t *, u_char *, int);
24947 +int Mpls_decodeLdpInitMsg(mplsLdpInitMsg_t *, u_char *, int);
24948 +int Mpls_encodeLdpCsp(mplsLdpCspTlv_t *, u_char *, int);
24949 +int Mpls_decodeLdpCsp(mplsLdpCspTlv_t *, u_char *, int);
24950 +int Mpls_encodeLdpBaseMsg(mplsLdpMsg_t *, u_char *, int);
24951 +int Mpls_decodeLdpBaseMsg(mplsLdpMsg_t *, u_char *, int);
24952 +int Mpls_encodeLdpFrLblRng(mplsLdpFrLblRng_t *, u_char *, int);
24953 +int Mpls_decodeLdpFrLblRng(mplsLdpFrLblRng_t *, u_char *, int);
24954 +int Mpls_encodeLdpFsp(mplsLdpFspTlv_t *, u_char *, int);
24955 +int Mpls_decodeLdpFsp(mplsLdpFspTlv_t *, u_char *, int);
24956 +int Mpls_encodeLdpNotMsg(mplsLdpNotifMsg_t *, u_char *, int);
24957 +int Mpls_decodeLdpNotMsg(mplsLdpNotifMsg_t *, u_char *, int);
24958 +int Mpls_encodeLdpStatus(mplsLdpStatusTlv_t *, u_char *, int);
24959 +int Mpls_decodeLdpStatus(mplsLdpStatusTlv_t *, u_char *, int);
24960 +int Mpls_encodeLdpExStatus(mplsLdpExStatusTlv_t *, u_char *, int);
24961 +int Mpls_decodeLdpExStatus(mplsLdpExStatusTlv_t *, u_char *, int);
24962 +int Mpls_encodeLdpRetPdu(mplsLdpRetPduTlv_t *, u_char *, int);
24963 +int Mpls_decodeLdpRetPdu(mplsLdpRetPduTlv_t *, u_char *, int, u_short);
24964 +int Mpls_encodeLdpRetMsg(mplsLdpRetMsgTlv_t *, u_char *, int);
24965 +int Mpls_decodeLdpRetMsg(mplsLdpRetMsgTlv_t *, u_char *, int, u_short);
24966 +int Mpls_encodeLdpHelloMsg(mplsLdpHelloMsg_t *, u_char *, int);
24967 +int Mpls_decodeLdpHelloMsg(mplsLdpHelloMsg_t *, u_char *, int);
24968 +int Mpls_encodeLdpChp(mplsLdpChpTlv_t *, u_char *, int);
24969 +int Mpls_decodeLdpChp(mplsLdpChpTlv_t *, u_char *, int);
24970 +int Mpls_encodeLdpCsn(mplsLdpCsnTlv_t *, u_char *, int);
24971 +int Mpls_decodeLdpCsn(mplsLdpCsnTlv_t *, u_char *, int);
24972 +int Mpls_encodeLdpTrAdr(mplsLdpTrAdrTlv_t *, u_char *, int);
24973 +int Mpls_decodeLdpTrAdr(mplsLdpTrAdrTlv_t *, u_char *, int);
24974 +int Mpls_encodeLdpKeepAliveMsg(mplsLdpKeepAlMsg_t *, u_char *, int);
24975 +int Mpls_decodeLdpKeepAliveMsg(mplsLdpKeepAlMsg_t *, u_char *, int);
24976 +int Mpls_encodeLdpAdrTlv(mplsLdpAdrTlv_t *, u_char *, int);
24977 +int Mpls_decodeLdpAdrTlv(mplsLdpAdrTlv_t *, u_char *, int, u_short);
24978 +int Mpls_encodeLdpAdrMsg(mplsLdpAdrMsg_t *, u_char *, int);
24979 +int Mpls_decodeLdpAdrMsg(mplsLdpAdrMsg_t *, u_char *, int);
24980 +int Mpls_encodeLdpFecTlv(mplsLdpFecTlv_t *, u_char *, int);
24981 +int Mpls_decodeLdpFecTlv(mplsLdpFecTlv_t *, u_char *, int, u_short);
24982 +int Mpls_encodeLdpGenLblTlv(mplsLdpGenLblTlv_t *, u_char *, int);
24983 +int Mpls_decodeLdpGenLblTlv(mplsLdpGenLblTlv_t *, u_char *, int);
24984 +int Mpls_encodeLdpAtmLblTlv(mplsLdpAtmLblTlv_t *, u_char *, int);
24985 +int Mpls_decodeLdpAtmLblTlv(mplsLdpAtmLblTlv_t *, u_char *, int);
24986 +int Mpls_encodeLdpFrLblTlv(mplsLdpFrLblTlv_t *, u_char *, int);
24987 +int Mpls_decodeLdpFrLblTlv(mplsLdpFrLblTlv_t *, u_char *, int);
24988 +int Mpls_encodeLdpHopTlv(mplsLdpHopTlv_t *, u_char *, int);
24989 +int Mpls_decodeLdpHopTlv(mplsLdpHopTlv_t *, u_char *, int);
24990 +int Mpls_encodeLdpLblMsgIdTlv(mplsLdpLblMsgIdTlv_t *, u_char *, int);
24991 +int Mpls_decodeLdpLblMsgIdTlv(mplsLdpLblMsgIdTlv_t *, u_char *, int);
24992 +int Mpls_encodeLdpPathVectorTlv(mplsLdpPathTlv_t *, u_char *, int);
24993 +int Mpls_decodeLdpPathVectorTlv(mplsLdpPathTlv_t *, u_char *, int, u_short);
24994 +int Mpls_encodeLdpLblMapMsg(mplsLdpLblMapMsg_t *, u_char *, int);
24995 +int Mpls_decodeLdpLblMapMsg(mplsLdpLblMapMsg_t *, u_char *, int);
24996 +int Mpls_encodeLdpFecAdrEl(mplsFecElement_t *, u_char *, int, u_char);
24997 +int Mpls_decodeLdpFecAdrEl(mplsFecElement_t *, u_char *, int, u_char);
24998 +int Mpls_encodeLdpLblRetMsgIdTlv(mplsLdpLblRetMsgIdTlv_t *, u_char *, int);
24999 +int Mpls_decodeLdpLblRetMsgIdTlv(mplsLdpLblRetMsgIdTlv_t *, u_char *, int);
25000 +int Mpls_encodeLdpLbl_W_R_Msg(mplsLdpLbl_W_R_Msg_t *, u_char *, int);
25001 +int Mpls_decodeLdpLbl_W_R_Msg(mplsLdpLbl_W_R_Msg_t *, u_char *, int);
25002 +int Mpls_encodeLdpERTlv(mplsLdpErTlv_t *, u_char *, int);
25003 +int Mpls_decodeLdpERTlv(mplsLdpErTlv_t *, u_char *, int, u_short);
25004 +int Mpls_encodeLdpErHop(mplsLdpErHop_t *, u_char *, int, u_short);
25005 +int Mpls_decodeLdpErHop(mplsLdpErHop_t *, u_char *, int, u_short *);
25006 +int Mpls_encodeLdpTrafficTlv(mplsLdpTrafficTlv_t *, u_char *, int);
25007 +int Mpls_decodeLdpTrafficTlv(mplsLdpTrafficTlv_t *, u_char *, int, u_short);
25008 +int Mpls_encodeLdpLblReqMsg(mplsLdpLblReqMsg_t *, u_char *, int);
25009 +int Mpls_decodeLdpLblReqMsg(mplsLdpLblReqMsg_t *, u_char *, int);
25010 +int Mpls_encodeLdpPreemptTlv(mplsLdpPreemptTlv_t *, u_char *, int);
25011 +int Mpls_decodeLdpPreemptTlv(mplsLdpPreemptTlv_t *, u_char *, int);
25012 +int Mpls_encodeLdpLspIdTlv(mplsLdpLspIdTlv_t *, u_char *, int);
25013 +int Mpls_decodeLdpLspIdTlv(mplsLdpLspIdTlv_t *, u_char *, int);
25014 +int Mpls_encodeLdpResClsTlv(mplsLdpResClsTlv_t *, u_char *, int);
25015 +int Mpls_decodeLdpResClsTlv(mplsLdpResClsTlv_t *, u_char *, int);
25016 +int Mpls_encodeLdpPinningTlv(mplsLdpPinningTlv_t *, u_char *, int);
25017 +int Mpls_decodeLdpPinningTlv(mplsLdpPinningTlv_t *, u_char *, int);
25018 +int Mpls_encodeLdpLblAbortMsg(mplsLdpLblAbortMsg_t *, u_char *, int);
25019 +int Mpls_decodeLdpLblAbortMsg(mplsLdpLblAbortMsg_t *, u_char *, int);
25022 + * DEBUG function declarations
25023 + */
25025 +void printTlv(mpls_instance_handle handle, mplsLdpTlv_t *);
25026 +void printHeader(mpls_instance_handle handle, mplsLdpHeader_t *);
25027 +void printCspFlags(mpls_instance_handle handle, mplsLdpCspFlag_t *);
25028 +void printCspFlagsPerByte(mpls_instance_handle handle, u_short *);
25029 +void printCspTlv(mpls_instance_handle handle, mplsLdpCspTlv_t *);
25030 +void printAspFlags(mpls_instance_handle handle, mplsLdpSPFlag_t *);
25031 +void printAspFlagsPerByte(mpls_instance_handle handle, u_int *);
25032 +void printAspTlv(mpls_instance_handle handle, mplsLdpAspTlv_t *);
25033 +void printFspFlags(mpls_instance_handle handle, mplsLdpSPFlag_t *);
25034 +void printFspTlv(mpls_instance_handle handle, mplsLdpFspTlv_t *);
25035 +void printRetMsgTlv(mpls_instance_handle handle, mplsLdpRetMsgTlv_t *);
25036 +void printRetPduTlv(mpls_instance_handle handle, mplsLdpRetPduTlv_t *);
25037 +void printExStatusTlv(mpls_instance_handle handle, mplsLdpExStatusTlv_t *);
25038 +void printStatusTlv(mpls_instance_handle handle, mplsLdpStatusTlv_t *);
25039 +void printCsnTlv(mpls_instance_handle handle, mplsLdpCsnTlv_t *);
25040 +void printTrAdrTlv(mpls_instance_handle handle, mplsLdpTrAdrTlv_t *);
25041 +void printChpTlv(mpls_instance_handle handle, mplsLdpChpTlv_t *);
25042 +void printAdrListTlv(mpls_instance_handle handle, mplsLdpAdrTlv_t *);
25043 +void printFecListTlv(mpls_instance_handle handle, mplsLdpFecTlv_t *);
25044 +void printLblMsgIdTlv(mpls_instance_handle handle, mplsLdpLblMsgIdTlv_t *);
25045 +void printPathVecTlv(mpls_instance_handle handle, mplsLdpPathTlv_t *);
25046 +void printHopTlv(mpls_instance_handle handle, mplsLdpHopTlv_t *);
25047 +void printFrLblTlv(mpls_instance_handle handle, mplsLdpFrLblTlv_t *);
25048 +void printAtmLblTlv(mpls_instance_handle handle, mplsLdpAtmLblTlv_t *);
25049 +void printGenLblTlv(mpls_instance_handle handle, mplsLdpGenLblTlv_t *);
25050 +void printErFlags(mpls_instance_handle handle, mplsLdpErFlag_t *);
25051 +void printErIPFlags(mpls_instance_handle handle, mplsLdpErIPFlag_t *);
25052 +void printErTlv(mpls_instance_handle handle, mplsLdpErTlv_t *);
25053 +void printTrafficTlv(mpls_instance_handle handle, mplsLdpTrafficTlv_t *);
25054 +void printAtmLabel(mpls_instance_handle handle, mplsLdpAtmLblRng_t *, int);
25055 +void printFspLabel(mpls_instance_handle handle, mplsLdpFrLblRng_t *, int);
25056 +void printErHop(mpls_instance_handle handle, mplsLdpErHop_t *, u_short);
25057 +void printPreemptTlv(mpls_instance_handle handle, mplsLdpPreemptTlv_t *);
25058 +void printLspIdTlv(mpls_instance_handle handle, mplsLdpLspIdTlv_t *);
25059 +void printResClsTlv(mpls_instance_handle handle, mplsLdpResClsTlv_t *);
25060 +void printPinningTlv(mpls_instance_handle handle, mplsLdpPinningTlv_t *);
25062 +void printInitMsg(mpls_instance_handle handle, mplsLdpInitMsg_t *);
25063 +void printHelloMsg(mpls_instance_handle handle, mplsLdpHelloMsg_t *);
25064 +void printNotMsg(mpls_instance_handle handle, mplsLdpNotifMsg_t *);
25065 +void printKeepAliveMsg(mpls_instance_handle handle, mplsLdpKeepAlMsg_t *);
25066 +void printAddressMsg(mpls_instance_handle handle, mplsLdpAdrMsg_t *);
25067 +void printLlbMapMsg(mpls_instance_handle handle, mplsLdpLblMapMsg_t *);
25068 +void printLlbReqMsg(mpls_instance_handle handle, mplsLdpLblReqMsg_t *);
25069 +void printLbl_W_R_Msg(mpls_instance_handle handle, mplsLdpLbl_W_R_Msg_t *);
25070 +void printLlbAbortMsg(mpls_instance_handle handle, mplsLdpLblAbortMsg_t *);
25072 +int converAsciiToHex(u_char *, int, u_char *);
25073 +int converHexToAscii(u_char *, int, u_char *);
25075 +#endif /* _LDP_MPLS_H_ */
25076 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_notif.c quagga-mpls/ldpd/ldp_notif.c
25077 --- quagga/ldpd/ldp_notif.c 1969-12-31 18:00:00.000000000 -0600
25078 +++ quagga-mpls/ldpd/ldp_notif.c 2006-08-09 21:56:11.000000000 -0500
25079 @@ -0,0 +1,375 @@
25082 + * Copyright (C) James R. Leu 2000
25083 + * jleu@mindspring.com
25085 + * This software is covered under the LGPL, for more
25086 + * info check out http://www.gnu.org/copyleft/lgpl.html
25087 + */
25089 +#include "ldp_struct.h"
25090 +#include "ldp_notif.h"
25091 +#include "ldp_attr.h"
25092 +#include "ldp_session.h"
25093 +#include "ldp_nexthop.h"
25094 +#include "ldp_entity.h"
25095 +#include "ldp_mesg.h"
25096 +#include "ldp_pdu_setup.h"
25097 +#include "ldp_label_request.h"
25098 +#include "ldp_label_mapping.h"
25099 +#include "ldp_fec.h"
25101 +#include "mpls_trace_impl.h"
25102 +#include "mpls_timer_impl.h"
25104 +void ldp_notif_prepare_msg(ldp_mesg * msg, uint32_t msgid, ldp_attr * r_attr,
25105 + ldp_notif_status status)
25107 + mplsLdpNotifMsg_t *notif = NULL;
25108 + int error, forward = 0;
25109 + uint32_t msg_type = 0;
25110 + uint32_t msg_id = 0;
25112 + ldp_mesg_prepare(msg, MPLS_NOT_MSGTYPE, msgid);
25113 + notif = &msg->u.notif;
25115 + notif->statusTlvExists = 1;
25117 + /* we have to pass two more parameters one is F bit and other is E bit
25118 + E = 1 if it is a fatal error, 0 is for advisory notification
25119 + F = 1 then notification has to be forwarded. */
25121 + /* check to set the E bit */
25122 + if (status == LDP_NOTIF_SUCCESS ||
25123 + status == LDP_NOTIF_UNKNOWN_MESG ||
25124 + status == LDP_NOTIF_UNKNOWN_TVL ||
25125 + status == LDP_NOTIF_LOOP_DETECTED ||
25126 + status == LDP_NOTIF_UNKNOWN_FEC ||
25127 + status == LDP_NOTIF_NO_ROUTE ||
25128 + status == LDP_NOTIF_NO_LABEL_RESOURCES_AVAILABLE ||
25129 + status == LDP_NOTIF_LABEL_RESOURCES_AVAILABLE ||
25130 + status == LDP_NOTIF_LABEL_ABORT ||
25131 + status == LDP_NOTIF_MISSING_MSG_PARAMS || status == LDP_NOTIF_UNSUPORTED_AF) {
25132 + error = 0;
25133 + } else {
25134 + error = 1;
25137 + /* check to set the F bit */
25138 + if (status == LDP_NOTIF_LOOP_DETECTED ||
25139 + status == LDP_NOTIF_UNKNOWN_FEC || status == LDP_NOTIF_NO_ROUTE) {
25140 + forward = 1;
25141 + } else {
25142 + forward = 0;
25145 + if (r_attr) {
25146 + switch (r_attr->state) {
25147 + case LDP_LSP_STATE_ABORT_RECV:
25148 + msg_type = MPLS_LBLABORT_MSGTYPE;
25149 + msg_id = r_attr->msg_id;
25150 + break;
25151 + default:
25152 + msg_type = 0;
25155 + notif->baseMsg.msgLength += setupStatusTlv(&notif->status, error, forward,
25156 + status, msg_id, msg_type);
25158 + /* We have to insert other tlv's like retpdu,extended status, returned
25159 + message
25160 + notif->exStatusTlvExists = 1;
25161 + notif->retPduTlvExists = 1;
25162 + */
25165 +mpls_return_enum ldp_notif_send(ldp_global * g, ldp_session * s,
25166 + ldp_attr * r_attr, ldp_notif_status status)
25168 + LDP_ENTER(g->user_data, "ldp_notif_send");
25170 + ldp_notif_prepare_msg(s->tx_message, g->message_identifier++, r_attr, status);
25172 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_LABEL,
25173 + "Notification Sent(%d)\n", s->index);
25175 + if (ldp_mesg_send_tcp(g, s, s->tx_message) == MPLS_FAILURE) {
25176 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_SEND, LDP_TRACE_FLAG_ERROR,
25177 + "Notification Send failed\n");
25178 + goto ldp_notif_send_error;
25181 + LDP_EXIT(g->user_data, "ldp_notif_send");
25182 + return MPLS_SUCCESS;
25184 +ldp_notif_send_error:
25186 + LDP_EXIT(g->user_data, "ldp_notif_send_error");
25187 + return MPLS_FAILURE;
25190 +void not2attr(mplsLdpNotifMsg_t * not, ldp_attr * attr, uint32_t flag)
25192 + attr->msg_id = not->baseMsg.msgId;
25194 + if (not->statusTlvExists && flag & LDP_ATTR_STATUS) {
25195 + memcpy(&attr->statusTlv, &not->status, sizeof(mplsLdpStatusTlv_t));
25196 + attr->statusTlvExists = 1;
25198 + if (not->lspidTlvExists && flag & LDP_ATTR_LSPID) {
25199 + memcpy(&attr->lspidTlv, &not->lspidTlv, sizeof(mplsLdpLspIdTlv_t));
25200 + attr->lspidTlvExists = 1;
25203 + if (not->retMsgTlvExists && flag & LDP_ATTR_MSGID) {
25204 + memcpy(&attr->retMsgTlv, &not->retMsg, sizeof(mplsLdpLblMsgIdTlv_t));
25205 + attr->retMsgTlvExists = 1;
25207 + /* Attribute types are not defined in ldp_attr.h file need to
25208 + define these optional Tlv types */
25210 + /*if(not->exStatusTlvExists && flag & LDP_ATTR_HOPCOUNT) {
25211 + memcpy(&attr->exStatus,&not->exStatus,sizeof(mplsLdpHopTlv_t));
25212 + attr->exStatusTlvExists = 1;
25214 + if(not->retPduTlvExists && flag & LDP_ATTR_PATH) {
25215 + memcpy(&attr->retPdu,&not->retPdu,sizeof(mplsLdpPathTlv_t));
25216 + attr->retPduTlvExists = 1;
25217 + } */
25220 +mpls_return_enum ldp_notif_process(ldp_global * g, ldp_session * s,
25221 + ldp_adj * a, ldp_entity * e, ldp_attr * r_attr)
25223 + mpls_return_enum retval = MPLS_SUCCESS;
25224 + int status;
25226 + LDP_ENTER(g->user_data, "ldp_notif_process");
25228 + status = r_attr->statusTlv.flags.flags.status;
25230 + switch (status) {
25231 + case LDP_NOTIF_LABEL_ABORT:
25232 + retval = ldp_notif_label_request_aborted(g, s, r_attr);
25233 + break;
25234 + case LDP_NOTIF_NO_LABEL_RESOURCES_AVAILABLE:
25235 + retval = ldp_notif_no_label_resources(g, s, r_attr);
25236 + break;
25237 + case LDP_NOTIF_NO_ROUTE:
25238 + case LDP_NOTIF_LOOP_DETECTED:
25239 + retval = ldp_notif_no_route(g, s, e, r_attr);
25240 + break;
25241 + case LDP_NOTIF_LABEL_RESOURCES_AVAILABLE:
25242 + retval = ldp_notif_label_resources_available(g, s, r_attr);
25243 + break;
25244 + case LDP_NOTIF_SUCCESS:
25245 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_SUCCESS:\n");
25246 + break;
25247 + case LDP_NOTIF_BAD_LDP_ID:
25248 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_BAD_LDP_ID:\n");
25249 + break;
25250 + case LDP_NOTIF_BAD_PROTO:
25251 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_BAD_PROTO:\n");
25252 + break;
25253 + case LDP_NOTIF_BAD_PDU_LEN:
25254 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_BAD_PDU_LEN:\n");
25255 + break;
25256 + case LDP_NOTIF_UNKNOWN_MESG:
25257 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_UNKNOWN_MESG:\n");
25258 + break;
25259 + case LDP_NOTIF_BAD_MESG_LEN:
25260 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_BAD_MESG_LEN:\n");
25261 + break;
25262 + case LDP_NOTIF_UNKNOWN_TVL:
25263 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_UNKNOWN_TVL:\n");
25264 + break;
25265 + case LDP_NOTIF_BAD_TLV_LEN:
25266 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_BAD_TLV_LEN:\n");
25267 + break;
25268 + case LDP_NOTIF_MALFORMED_TLV:
25269 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_MALFORMED_TLV:\n");
25270 + break;
25271 + case LDP_NOTIF_HOLD_TIMER_EXPIRED:
25272 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_HOLD_TIMER_EXPIRED:\n");
25273 + break;
25274 + case LDP_NOTIF_SHUTDOWN:
25275 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_SHUTDOWN:\n");
25276 + break;
25277 + case LDP_NOTIF_UNKNOWN_FEC:
25278 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_UNKNOWN_FEC:\n");
25279 + break;
25280 + case LDP_NOTIF_SESSION_REJECTED_NO_HELLO:
25281 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_SESSION_REJECTED_NO_HELLO:\n");
25282 + break;
25283 + case LDP_NOTIF_SESSION_REJECTED_PARAMETERS_ADVERTISEMENT_MODE:
25284 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_SESSION_REJECTED_PARAMETERS_ADVERTISEMENT_MODE:\n");
25285 + break;
25286 + case LDP_NOTIF_SESSION_REJECTED_PARAMETERS_MAX_PDU_LEN:
25287 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_SESSION_REJECTED_PARAMETERS_MAX_PDU_LEN:\n");
25288 + break;
25289 + case LDP_NOTIF_SESSION_REJECTED_PARAMETERS_LABEL_RANGE:
25290 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_SESSION_REJECTED_PARAMETERS_LABEL_RANGE:\n");
25291 + break;
25292 + case LDP_NOTIF_KEEPALIVE_TIMER_EXPIRED:
25293 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_KEEPALIVE_TIMER_EXPIRED:\n");
25294 + break;
25295 + case LDP_NOTIF_MISSING_MSG_PARAMS:
25296 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_MISSING_MSG_PARAMS:\n");
25297 + break;
25298 + case LDP_NOTIF_UNSUPORTED_AF:
25299 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_UNSUPORTED_AF:\n");
25300 + break;
25301 + case LDP_NOTIF_SESSION_REJECTED_BAD_KEEPALIVE_TIME:
25302 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_SESSION_REJECTED_BAD_KEEPALIVE_TIME:\n");
25303 + break;
25304 + case LDP_NOTIF_INTERNAL_ERROR:
25305 + LDP_TRACE_OUT(g->user_data, "LDP_NOTIF_INTERNAL_ERROR\n");
25306 + break;
25307 + default:
25308 + LDP_TRACE_OUT(g->user_data, "Receive an unknown notification: %08x\n",
25309 + status);
25310 + retval = MPLS_SUCCESS;
25311 + break;
25314 + LDP_EXIT(g->user_data, "ldp_notif_process");
25315 + return retval;
25318 +mpls_return_enum ldp_notif_label_request_aborted(ldp_global * g, ldp_session * s,
25319 + ldp_attr * r_attr)
25321 + ldp_attr *ds_attr = NULL;
25323 + LDP_ENTER(g->user_data, "ldp_notif_label_request_aborted");
25325 + ds_attr = MPLS_LIST_HEAD(&s->attr_root);
25326 + while (ds_attr != NULL) {
25327 + if (ds_attr->state == LDP_LSP_STATE_ABORT_SENT &&
25328 + ds_attr->msg_id == r_attr->msg_id) {
25329 + break;
25331 + ds_attr = MPLS_LIST_NEXT(&s->attr_root, ds_attr, _fs);
25334 + if (ds_attr) { /* LRqA.1 */
25335 + ldp_attr_remove_complete(g, ds_attr, MPLS_BOOL_FALSE); /* LRqA.2 */
25337 + LDP_EXIT(g->user_data, "ldp_notif_label_request_aborted");
25338 + return MPLS_SUCCESS;
25341 + LDP_EXIT(g->user_data, "ldp_notif_label_request_abort_error");
25342 + return MPLS_FAILURE;
25345 +mpls_return_enum ldp_notif_no_label_resources(ldp_global * g, ldp_session * s,
25346 + ldp_attr * s_attr)
25348 + ldp_attr_list *ds_list = NULL;
25349 + ldp_attr *ds_attr = NULL;
25350 + mpls_fec nfec;
25352 + LDP_ENTER(g->user_data, "ldp_notif_no_label_resources");
25354 + fec_tlv2mpls_fec(&s_attr->fecTlv, 0, &nfec);
25355 + /* NoRes.1 do not actually remove from tree, just change it's state */
25357 + if ((ds_list = ldp_attr_find_downstream_all(g, s, &nfec))) {
25358 + ds_attr = MPLS_LIST_HEAD(&s->attr_root);
25359 + while (ds_attr) {
25360 + if (ds_attr->state == LDP_LSP_STATE_REQ_SENT) {
25361 + ds_attr->state = LDP_LSP_STATE_NO_LABEL_RESOURCE_RECV; /* NoRes.2 */
25363 + ds_attr = MPLS_LIST_NEXT(&s->attr_root, ds_attr, _fs);
25367 + s->no_label_resource_recv = MPLS_BOOL_TRUE; /* NoRes.3 */
25369 + LDP_EXIT(g->user_data, "ldp_notif_no_label_resource_error");
25370 + return MPLS_SUCCESS;
25373 +mpls_return_enum ldp_notif_no_route(ldp_global * g, ldp_session * s,
25374 + ldp_entity * e, ldp_attr * s_attr)
25376 + ldp_attr *ds_attr = NULL;
25377 + ldp_attr_list *ds_list = NULL;
25378 + mpls_fec nfec;
25379 + mpls_return_enum retval = MPLS_FAILURE;
25381 + LDP_ENTER(g->user_data, "ldp_notif_no_route\n");
25383 + fec_tlv2mpls_fec(&s_attr->fecTlv, 0, &nfec);
25385 + if ((ds_list = ldp_attr_find_downstream_all(g, s, &nfec))) {
25386 + ds_attr = MPLS_LIST_HEAD(&s->attr_root);
25387 + while (ds_attr) {
25388 + if (ds_attr->state == LDP_LSP_STATE_REQ_SENT) {
25389 + if (e->label_request_count) {
25390 + if (ds_attr->attempt_count < e->label_request_count) {
25391 + if (mpls_timer_handle_verify(g->timer_handle,
25392 + ds_attr->action_timer) == MPLS_BOOL_FALSE) {
25393 + ds_attr->action_timer =
25394 + mpls_timer_create(g->timer_handle, MPLS_UNIT_SEC,
25395 + s->cfg_label_request_timer, (void *)ds_attr, g,
25396 + ldp_attr_action_callback);
25398 + mpls_timer_start(g->timer_handle, ds_attr->action_timer,
25399 + MPLS_TIMER_ONESHOT);
25401 + retval = MPLS_SUCCESS;
25402 + } else {
25403 + ldp_attr_remove_complete(g, ds_attr, MPLS_BOOL_FALSE);
25404 + retval = MPLS_FAILURE;
25407 + ds_attr = MPLS_LIST_NEXT(&s->attr_root, ds_attr, _fs);
25411 + LDP_EXIT(g->user_data, "ldp_notif_no_route\n");
25412 + return retval;
25415 +/* IV. Receive Notification/ Loop Detected */
25417 +/* Algo: Same as receive Notification/No Route */
25419 +mpls_return_enum ldp_notif_label_resources_available(ldp_global * g,
25420 + ldp_session * s, ldp_attr * r_attr)
25422 + ldp_session *nh_session = NULL;
25423 + ldp_attr *ds_attr = NULL;
25424 + ldp_nexthop *nh = NULL;
25425 + ldp_fec *f = NULL;
25427 + LDP_ENTER(g->user_data, "ldp_notif_label_resources_available");
25429 + s->no_label_resource_recv = MPLS_BOOL_FALSE; /* Res.1 */
25431 + ds_attr = MPLS_LIST_HEAD(&s->attr_root);
25432 + while (ds_attr != NULL) { /* Res.2 */
25433 + if (ds_attr->state == LDP_LSP_STATE_NO_LABEL_RESOURCE_RECV) {
25434 + f = ds_attr->fec;
25435 + nh = MPLS_LIST_HEAD(&f->nh_root);
25436 + while (nh) {
25437 + nh_session = ldp_session_for_nexthop(nh);
25438 + if (nh_session && (nh_session->index == s->index)) {
25439 + /* Res.4 */
25440 + if (ldp_label_request_send(g, s, ds_attr, NULL) != MPLS_SUCCESS) {
25441 + MPLS_ASSERT(0);
25443 + } else {
25444 + ldp_attr_remove_complete(g, ds_attr, MPLS_BOOL_FALSE);/* Res.5 */
25446 + nh = MPLS_LIST_NEXT(&f->nh_root, nh, _fec);
25449 + ds_attr = MPLS_LIST_NEXT(&s->attr_root, ds_attr, _fs);
25450 + } /* Res.6 */
25452 + LDP_EXIT(g->user_data, "ldp_notif_label_resources_available");
25453 + return MPLS_SUCCESS;
25455 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_notif.h quagga-mpls/ldpd/ldp_notif.h
25456 --- quagga/ldpd/ldp_notif.h 1969-12-31 18:00:00.000000000 -0600
25457 +++ quagga-mpls/ldpd/ldp_notif.h 2006-08-09 21:56:16.000000000 -0500
25458 @@ -0,0 +1,36 @@
25461 + * Copyright (C) James R. Leu 2000
25462 + * jleu@mindspring.com
25464 + * This software is covered under the LGPL, for more
25465 + * info check out http://www.gnu.org/copyleft/lgpl.html
25466 + */
25468 +#ifndef _LDP_NOTIF_H_
25469 +#define _LDP_NOTIF_H_
25471 +#include "ldp_struct.h"
25473 +extern mpls_return_enum ldp_notif_send(ldp_global *, ldp_session *, ldp_attr *,
25475 + ldp_notif_status);
25477 +extern mpls_return_enum ldp_notif_process(ldp_global * g, ldp_session * s,
25478 + ldp_adj * a, ldp_entity * e, ldp_attr * r_attr);
25480 +extern void not2attr(mplsLdpNotifMsg_t * not, ldp_attr * attr, uint32_t flag);
25482 +extern mpls_return_enum ldp_notif_no_route(ldp_global * g, ldp_session * s,
25483 + ldp_entity * e, ldp_attr * attr);
25485 +extern mpls_return_enum ldp_notif_no_label_resources(ldp_global * g,
25486 + ldp_session * s, ldp_attr * s_attr);
25488 +extern mpls_return_enum ldp_notif_label_request_aborted(ldp_global * g,
25489 + ldp_session * s, ldp_attr * s_attr);
25491 +extern mpls_return_enum ldp_notif_label_resources_available(ldp_global * g,
25492 + ldp_session * s, ldp_attr * s_attr);
25494 +#endif
25495 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_outlabel.c quagga-mpls/ldpd/ldp_outlabel.c
25496 --- quagga/ldpd/ldp_outlabel.c 1969-12-31 18:00:00.000000000 -0600
25497 +++ quagga-mpls/ldpd/ldp_outlabel.c 2006-12-07 22:01:55.000000000 -0600
25498 @@ -0,0 +1,235 @@
25501 + * Copyright (C) James R. Leu 2000
25502 + * jleu@mindspring.com
25504 + * This software is covered under the LGPL, for more
25505 + * info check out http://www.gnu.org/copyleft/lgpl.html
25506 + */
25508 +#include <stdlib.h>
25509 +#include "ldp_struct.h"
25510 +#include "ldp_addr.h"
25511 +#include "ldp_if.h"
25512 +#include "ldp_attr.h"
25513 +#include "ldp_fec.h"
25514 +#include "ldp_nexthop.h"
25515 +#include "ldp_outlabel.h"
25516 +#include "ldp_inlabel.h"
25517 +#include "ldp_session.h"
25518 +#include "ldp_tunnel.h"
25519 +#include "ldp_global.h"
25521 +#include "mpls_mm_impl.h"
25522 +#include "mpls_trace_impl.h"
25524 +static uint32_t _ldp_outlabel_next_index = 1;
25527 + * even through we're trying to mimic what FECs/addrs/interfaces are doing
25528 + * with respect to being added to the global list upon create and
25529 + * automagically be removed from the global list upon delete, we have to
25530 + * change thing up for outlabels. We want the global add/delete to call
25531 + * the porting layer to install the segments, but an outlabel needs more
25532 + * info then just being allocated before the porting layer can add it.
25533 + * so ldp_outlabel_create is not in charge of adding to the global list.
25534 + * Instead the only entrance to creating a outlabel is
25535 + * ldp_outlabel_create_complete which uses ldp_outlabel_create just to
25536 + * allocate and initialize the memory, then after all of the necessary info
25537 + * has been attached, it is added to the global list, which calls the
25538 + * porting layer
25539 + */
25541 +static ldp_outlabel *ldp_outlabel_create(ldp_global * g)
25543 + ldp_outlabel *o = (ldp_outlabel *) mpls_malloc(sizeof(ldp_outlabel));
25545 + if (o) {
25546 + memset(o, 0, sizeof(ldp_outlabel));
25547 + MPLS_REFCNT_INIT(o, 0);
25548 + MPLS_LIST_INIT(&o->inlabel_root, ldp_inlabel);
25549 + MPLS_LIST_INIT(&o->tunnel_root, ldp_tunnel);
25550 + MPLS_LIST_INIT(&o->nh_root, ldp_nexthop);
25551 + MPLS_LIST_ELEM_INIT(o, _global);
25552 + MPLS_LIST_ELEM_INIT(o, _session);
25553 + o->index = _ldp_outlabel_get_next_index();
25554 + o->info.label.type = MPLS_LABEL_TYPE_NONE;
25555 + o->switching = MPLS_BOOL_FALSE;
25557 + return o;
25560 +ldp_outlabel *ldp_outlabel_create_complete(ldp_global * g, ldp_session * s,
25561 + ldp_attr * a, ldp_nexthop *nh)
25563 + ldp_outlabel *out = ldp_outlabel_create(g);
25565 + if (out != NULL) {
25566 + ldp_outlabel_add_nexthop2(out, nh);
25567 + ldp_session_add_outlabel(s, out);
25569 + out->info.push_label = MPLS_BOOL_TRUE;
25570 + out->info.owner = MPLS_OWNER_LDP;
25572 + ldp_attr2mpls_label_struct(a, &out->info.label);
25573 + ldp_attr_add_outlabel(a, out);
25575 + /* _ldp_global_add_outlabel must be last so the porting layer has all the
25576 + * info needed for installing the label */
25577 + _ldp_global_add_outlabel(g, out);
25579 + return out;
25582 +void ldp_outlabel_delete(ldp_global * g, ldp_outlabel * o)
25584 + LDP_PRINT(g->user_data,"outlabel delete");
25585 + MPLS_REFCNT_ASSERT(o, 0);
25586 + if (o->nh) {
25587 + ldp_outlabel_del_nexthop2(g, o);
25589 + _ldp_global_del_outlabel(g, o);
25590 + mpls_free(o);
25593 +#if 0
25594 +void ldp_outlabel_delete_complete(ldp_global * g, ldp_outlabel * out)
25596 + ldp_attr_del_outlabel(g, out->attr);
25597 + if (out->session) {
25598 + ldp_session_del_outlabel(g, out->session, out);
25600 + _ldp_global_del_outlabel(g, out);
25601 + ldp_outlabel_del_nexthop2(g, out);
25603 +#endif
25605 +void _ldp_outlabel_add_inlabel(ldp_outlabel * o, ldp_inlabel * i)
25607 + MPLS_ASSERT(o && i);
25608 + MPLS_REFCNT_HOLD(i);
25609 + o->merge_count++;
25610 + MPLS_LIST_ADD_HEAD(&o->inlabel_root, i, _outlabel, ldp_inlabel);
25613 +void _ldp_outlabel_del_inlabel(ldp_global * g,ldp_outlabel * o, ldp_inlabel * i)
25615 + MPLS_ASSERT(o && i);
25616 + MPLS_LIST_REMOVE(&o->inlabel_root, i, _outlabel);
25617 + o->merge_count--;
25618 + MPLS_REFCNT_RELEASE2(g, i, ldp_inlabel_delete);
25621 +void _ldp_outlabel_add_attr(ldp_outlabel * o, ldp_attr * a)
25623 + MPLS_ASSERT(o && a);
25624 + MPLS_REFCNT_HOLD(a);
25625 + o->attr = a;
25628 +void _ldp_outlabel_del_attr(ldp_global *g, ldp_outlabel * o)
25630 + MPLS_ASSERT(o && o->attr);
25631 + MPLS_REFCNT_RELEASE2(g, o->attr, ldp_attr_delete);
25632 + o->attr = NULL;
25636 + * We do not hold a ref to the nexthop. The nexthop holds a ref to the
25637 + * outlabel. Nexthop creation calls ldp_outlabel_add_nexthop, nexthop
25638 + * deletion calls ldp_outlabel_del_nexthop. There is no way a nexthop can
25639 + * be deleted without removing the outlabels ref to the nexthop.
25641 + * this is for the nexthops outlabel used
25642 + * for describing hierachy
25643 + */
25644 +void ldp_outlabel_add_nexthop(ldp_outlabel * o, ldp_nexthop * nh)
25646 + ldp_nexthop *np = NULL;
25648 + MPLS_ASSERT(o && nh);
25650 + ldp_nexthop_add_outlabel(nh,o);
25652 + np = MPLS_LIST_HEAD(&o->nh_root);
25653 + while (np != NULL) {
25654 + if (np->index > nh->index) {
25655 + MPLS_LIST_INSERT_BEFORE(&o->nh_root, np, nh, _outlabel);
25656 + return;
25658 + np = MPLS_LIST_NEXT(&o->nh_root, np, _outlabel);
25660 + MPLS_LIST_ADD_TAIL(&o->nh_root, nh, _outlabel, ldp_nexthop);
25664 + * this is for the nexthops outlabel used
25665 + * for describing hierachy
25666 + */
25667 +void ldp_outlabel_del_nexthop(ldp_global *g, ldp_outlabel * o, ldp_nexthop * nh)
25669 + MPLS_ASSERT(o && nh);
25670 + MPLS_LIST_REMOVE(&o->nh_root, nh, _outlabel);
25671 + ldp_nexthop_del_outlabel(g, nh);
25674 +/* this is for the outlabels nexthops, not the nexthop's outlabel
25675 + * used to describe hierarchy */
25676 +void ldp_outlabel_add_nexthop2(ldp_outlabel * o, ldp_nexthop * nh)
25678 + MPLS_ASSERT(o && nh);
25679 + MPLS_REFCNT_HOLD(nh);
25680 + o->nh = nh;
25681 + ldp_nexthop_add_outlabel2(nh, o);
25684 +/* this is for the outlabels nexthops, not the nexthop's outlabel
25685 + * used to describe hierarchy */
25686 +void ldp_outlabel_del_nexthop2(ldp_global *g, ldp_outlabel * o)
25688 + MPLS_ASSERT(o);
25689 + ldp_nexthop_del_outlabel2(g, o->nh, o);
25690 + MPLS_REFCNT_RELEASE2(g, o->nh, ldp_nexthop_delete);
25691 + o->nh = NULL;
25694 +void _ldp_outlabel_add_session(ldp_outlabel * o, ldp_session * s)
25696 + MPLS_ASSERT(o && s);
25697 + MPLS_REFCNT_HOLD(s);
25698 + o->session = s;
25701 +void _ldp_outlabel_del_session(ldp_outlabel * o)
25703 + MPLS_ASSERT(o && o->session);
25704 + MPLS_REFCNT_RELEASE(o->session, ldp_session_delete);
25705 + o->session = NULL;
25708 +void _ldp_outlabel_add_tunnel(ldp_outlabel * o, ldp_tunnel * t)
25710 + MPLS_ASSERT(o && t);
25711 + MPLS_REFCNT_HOLD(t);
25712 + o->merge_count++;
25713 + MPLS_LIST_ADD_HEAD(&o->tunnel_root, t, _outlabel, ldp_tunnel);
25716 +void _ldp_outlabel_del_tunnel(ldp_outlabel * o, ldp_tunnel * t)
25718 + MPLS_ASSERT(o && t);
25719 + MPLS_LIST_REMOVE(&o->tunnel_root, t, _outlabel);
25720 + o->merge_count--;
25721 + MPLS_REFCNT_RELEASE(t, ldp_tunnel_delete);
25724 +uint32_t _ldp_outlabel_get_next_index()
25726 + uint32_t retval = _ldp_outlabel_next_index;
25728 + _ldp_outlabel_next_index++;
25729 + if (retval > _ldp_outlabel_next_index) {
25730 + _ldp_outlabel_next_index = 1;
25732 + return retval;
25734 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_outlabel.h quagga-mpls/ldpd/ldp_outlabel.h
25735 --- quagga/ldpd/ldp_outlabel.h 1969-12-31 18:00:00.000000000 -0600
25736 +++ quagga-mpls/ldpd/ldp_outlabel.h 2006-10-16 22:35:13.000000000 -0500
25737 @@ -0,0 +1,40 @@
25740 + * Copyright (C) James R. Leu 2000
25741 + * jleu@mindspring.com
25743 + * This software is covered under the LGPL, for more
25744 + * info check out http://www.gnu.org/copyleft/lgpl.html
25745 + */
25747 +#ifndef _LDP_OUTLABEL_H_
25748 +#define _LDP_OUTLABEL_H_
25750 +#include "ldp_struct.h"
25752 +extern void ldp_outlabel_delete(ldp_global * g, ldp_outlabel * i);
25754 +extern ldp_outlabel *ldp_outlabel_create_complete(ldp_global * g,
25755 + ldp_session * s, ldp_attr * a, ldp_nexthop *nh);
25756 +extern void ldp_outlabel_delete_complete(ldp_global * g, ldp_outlabel * out);
25758 +extern void _ldp_outlabel_add_inlabel(ldp_outlabel *, ldp_inlabel *);
25759 +extern void _ldp_outlabel_del_inlabel(ldp_global *,ldp_outlabel *, ldp_inlabel *);
25761 +extern void _ldp_outlabel_add_session(ldp_outlabel *, ldp_session *);
25762 +extern void _ldp_outlabel_del_session(ldp_outlabel * o);
25764 +extern void _ldp_outlabel_add_attr(ldp_outlabel * o, ldp_attr * a);
25765 +extern void _ldp_outlabel_del_attr(ldp_global *g, ldp_outlabel * o);
25767 +extern void ldp_outlabel_add_nexthop(ldp_outlabel * o, ldp_nexthop * nh);
25768 +extern void ldp_outlabel_del_nexthop(ldp_global *g, ldp_outlabel * o, ldp_nexthop * nh);
25770 +extern void ldp_outlabel_add_nexthop2(ldp_outlabel * o, ldp_nexthop * nh);
25771 +extern void ldp_outlabel_del_nexthop2(ldp_global *g, ldp_outlabel * o);
25773 +extern void _ldp_outlabel_add_tunnel(ldp_outlabel * o, ldp_tunnel * t);
25774 +extern void _ldp_outlabel_del_tunnel(ldp_outlabel * o, ldp_tunnel * t);
25776 +extern uint32_t _ldp_outlabel_get_next_index();
25777 +#endif
25778 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_pdu.h quagga-mpls/ldpd/ldp_pdu.h
25779 --- quagga/ldpd/ldp_pdu.h 1969-12-31 18:00:00.000000000 -0600
25780 +++ quagga-mpls/ldpd/ldp_pdu.h 2006-08-09 21:56:13.000000000 -0500
25781 @@ -0,0 +1,32 @@
25784 + * Copyright (C) James R. Leu 2000
25785 + * jleu@mindspring.com
25787 + * This software is covered under the LGPL, for more
25788 + * info check out http://www.gnu.org/copyleft/lgpl.html
25789 + */
25791 +#ifndef _LDP_PDU_H_
25792 +#define _LDP_PDU_H_
25794 +#include "ldp_mm_impl.h"
25796 +#define MPLS_MSGMALLOC( e ) mplsLdp ## e ## Msg_t *test ## e ## Msg = (mplsLdp ## e ## Msg_t*)ldp_malloc(sizeof(mplsLdp ## e ## Msg_t))
25797 +#define MPLS_MSGSTRUCT( e ) mplsLdp ## e ## Msg_t test ## e ## Msg
25798 +#define MPLS_MSGPTR( e ) mplsLdp ## e ## Msg_t *test ## e ## Msg
25799 +#define MPLS_MSGCAST( e , f ) test ## e ## Msg = (mplsLdp ## e ## Msg_t*) f
25800 +#define MPLS_MSGPARAM( e ) test ## e ## Msg
25802 +#include "ldp_struct.h"
25804 +extern ldp_pdu *ldp_pdu_create();
25805 +extern ldp_pdu *ldp_pdu_create_decode(ldp_global * g, uint8_t * buf,
25806 + int buf_size, int data_size);
25807 +extern void ldp_pdu_delete(ldp_pdu * p);
25808 +extern int Mpls_encodeLdpPDU(ldp_global * g, uint32_t lsraddr, int label_space,
25809 + ldp_msg * msg, uint8_t * buf, int buf_size);
25810 +extern mpls_return_enum Mpls_decodeLdpPDU(ldp_global * g, ldp_pdu * pdu,
25811 + uint8_t * buf, int size, int n);
25813 +#endif
25814 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_pdu_setup.c quagga-mpls/ldpd/ldp_pdu_setup.c
25815 --- quagga/ldpd/ldp_pdu_setup.c 1969-12-31 18:00:00.000000000 -0600
25816 +++ quagga-mpls/ldpd/ldp_pdu_setup.c 2006-08-09 21:56:12.000000000 -0500
25817 @@ -0,0 +1,512 @@
25820 + * Copyright (C) James R. Leu 2000
25821 + * jleu@mindspring.com
25823 + * This software is covered under the LGPL, for more
25824 + * info check out http://www.gnu.org/copyleft/lgpl.html
25825 + */
25827 +#include "ldp_struct.h"
25828 +#include "ldp_pdu_setup.h"
25830 +void setBaseMsgId(mplsLdpMsg_t * baseMsg, unsigned int msgId)
25832 + baseMsg->msgId = msgId;
25835 +void setupBaseMsg(mplsLdpMsg_t * baseMsg, unsigned int type, int uBit,
25836 + unsigned int msgId)
25838 + baseMsg->flags.flags.msgType = type;
25839 + baseMsg->flags.flags.uBit = uBit;
25840 + baseMsg->msgLength = MPLS_MSGIDFIXLEN;
25841 + setBaseMsgId(baseMsg, msgId);
25844 +int setupChpTlv(mplsLdpChpTlv_t * chpTlv, int target, int request, int res,
25845 + int holdTime)
25847 + chpTlv->baseTlv.flags.flags.tBit = MPLS_CHP_TLVTYPE;
25848 + chpTlv->baseTlv.flags.flags.uBit = 0;
25849 + chpTlv->baseTlv.flags.flags.fBit = 0;
25850 + chpTlv->baseTlv.length = MPLS_CHPFIXLEN;
25851 + chpTlv->flags.flags.target = target;
25852 + chpTlv->flags.flags.request = request;
25853 + chpTlv->flags.flags.res = res;
25854 + chpTlv->holdTime = holdTime;
25855 + return MPLS_TLVFIXLEN + MPLS_CHPFIXLEN;
25858 +int setupPinningTlv(mplsLdpPinningTlv_t * pinningTlv, int pBit, int res)
25860 + pinningTlv->baseTlv.flags.flags.tBit = MPLS_PINNING_TLVTYPE;
25861 + pinningTlv->baseTlv.flags.flags.uBit = 0;
25862 + pinningTlv->baseTlv.flags.flags.fBit = 0;
25863 + pinningTlv->baseTlv.length = 4;
25864 + pinningTlv->flags.flags.pBit = pBit;
25865 + pinningTlv->flags.flags.res = res;
25866 + return 4 + MPLS_TLVFIXLEN;
25869 +int setupResClassTlv(mplsLdpResClsTlv_t * resClsTlv, unsigned int rsCls)
25871 + resClsTlv->baseTlv.flags.flags.tBit = MPLS_RESCLASS_TLVTYPE;
25872 + resClsTlv->baseTlv.flags.flags.uBit = 0;
25873 + resClsTlv->baseTlv.flags.flags.fBit = 0;
25874 + resClsTlv->baseTlv.length = 4;
25875 + resClsTlv->rsCls = rsCls;
25876 + return 4 + MPLS_TLVFIXLEN;
25879 +int setupPreemptTlv(mplsLdpPreemptTlv_t * preemptTlv, unsigned char setPrio,
25880 + unsigned char holdPrio, unsigned short res)
25882 + preemptTlv->baseTlv.flags.flags.tBit = MPLS_PREEMPT_TLVTYPE;
25883 + preemptTlv->baseTlv.flags.flags.uBit = 0;
25884 + preemptTlv->baseTlv.flags.flags.fBit = 0;
25885 + preemptTlv->baseTlv.length = MPLS_PREEMPTTLV_FIXLEN;
25886 + preemptTlv->setPrio = setPrio;
25887 + preemptTlv->holdPrio = holdPrio;
25888 + preemptTlv->res = res;
25889 + return MPLS_PREEMPTTLV_FIXLEN + MPLS_TLVFIXLEN;
25892 +int addErHop2ErHopTvl(mplsLdpErTlv_t * erHopTlv, mplsLdpErHop_t * erHop,
25893 + unsigned short type)
25895 + int num = erHopTlv->numberErHops;
25896 + int result = 0;
25898 + memcpy(&(erHopTlv->erHopArray[num]), erHop, sizeof(mplsLdpErHop_t));
25899 + erHopTlv->erHopTypes[num] = type;
25900 + erHopTlv->numberErHops++;
25901 + switch (type) {
25902 + case MPLS_ERHOP_IPV4_TLVTYPE:
25903 + result = MPLS_ERHOP_IPV4_FIXLEN;
25904 + break;
25905 + case MPLS_ERHOP_IPV6_TLVTYPE:
25906 + result = MPLS_ERHOP_IPV6_FIXLEN;
25907 + break;
25908 + case MPLS_ERHOP_AS_TLVTYPE:
25909 + result = MPLS_ERHOP_AS_FIXLEN;
25910 + break;
25911 + case MPLS_ERHOP_LSPID_TLVTYPE:
25912 + result = MPLS_ERHOP_LSPID_FIXLEN;
25913 + break;
25915 + return result + MPLS_TLVFIXLEN;
25918 +int setupErHopTlv(mplsLdpErTlv_t * erHopTlv)
25920 + erHopTlv->baseTlv.flags.flags.tBit = MPLS_ERHOP_IPV4_TLVTYPE;
25921 + erHopTlv->baseTlv.flags.flags.uBit = 0;
25922 + erHopTlv->baseTlv.flags.flags.fBit = 0;
25923 + erHopTlv->baseTlv.length = 0;
25924 + return MPLS_TLVFIXLEN;
25927 +int setupTrAddrTlv(mplsLdpTrAdrTlv_t * trAddrTlv, unsigned int trAddr)
25929 + trAddrTlv->baseTlv.flags.flags.tBit = MPLS_TRADR_TLVTYPE;
25930 + trAddrTlv->baseTlv.flags.flags.uBit = 0;
25931 + trAddrTlv->baseTlv.flags.flags.fBit = 0;
25932 + trAddrTlv->baseTlv.length = MPLS_TRADRFIXLEN;
25933 + trAddrTlv->address = trAddr;
25934 + return MPLS_TRADRFIXLEN + MPLS_TLVFIXLEN;
25937 +int setupCsnTlv(mplsLdpCsnTlv_t * csnTlv, unsigned int confSeqNum)
25939 + csnTlv->baseTlv.flags.flags.tBit = MPLS_CSN_TLVTYPE;
25940 + csnTlv->baseTlv.flags.flags.uBit = 0;
25941 + csnTlv->baseTlv.flags.flags.fBit = 0;
25942 + csnTlv->baseTlv.length = MPLS_CSNFIXLEN;
25943 + csnTlv->seqNumber = confSeqNum;
25944 + return MPLS_CSNFIXLEN + MPLS_TLVFIXLEN;
25947 +int setupCspTlv(mplsLdpCspTlv_t * cspTlv, uint16_t keepalive,
25948 + uint8_t adv_discp, uint8_t loop, uint8_t pvl, uint16_t mtu,
25949 + uint32_t remote_lsraddr, uint16_t remote_labelspace, uint32_t res)
25951 + cspTlv->baseTlv.flags.flags.tBit = MPLS_CSP_TLVTYPE;
25952 + cspTlv->baseTlv.flags.flags.uBit = 0;
25953 + cspTlv->baseTlv.flags.flags.fBit = 0;
25954 + cspTlv->baseTlv.length = MPLS_CSPFIXLEN;
25955 + cspTlv->protocolVersion = 1;
25956 + cspTlv->holdTime = keepalive;
25957 + cspTlv->flags.flags.lad = adv_discp;
25958 + cspTlv->flags.flags.ld = loop;
25959 + cspTlv->flags.flags.res = res;
25960 + cspTlv->flags.flags.pvl = pvl;
25961 + cspTlv->maxPduLen = mtu;
25962 + cspTlv->rcvLsrAddress = remote_lsraddr;
25963 + cspTlv->rcvLsId = remote_labelspace;
25964 + return MPLS_CSPFIXLEN + MPLS_TLVFIXLEN;
25967 +int addLblRng2AspTlv(mplsLdpAspTlv_t * aspTlv, unsigned int minvpi,
25968 + unsigned int minvci, unsigned int maxvpi, unsigned int maxvci)
25970 + int num = aspTlv->baseTlv.length / MPLS_ASPFIXLEN;
25972 + aspTlv->baseTlv.length += MPLS_ASPFIXLEN;
25973 + aspTlv->lblRngList[num].flags.flags.res1 = 0;
25974 + aspTlv->lblRngList[num].flags.flags.minVpi = minvpi;
25975 + aspTlv->lblRngList[num].flags.flags.minVci = minvci;
25976 + aspTlv->lblRngList[num].flags.flags.res2 = 0;
25977 + aspTlv->lblRngList[num].flags.flags.maxVpi = maxvpi;
25978 + aspTlv->lblRngList[num].flags.flags.maxVci = maxvci;
25979 + return MPLS_ASPFIXLEN;
25982 +int addLblRng2FspTlv(mplsLdpFspTlv_t * fspTlv, unsigned int resmin,
25983 + unsigned int len, unsigned int mindlci, unsigned int resmax,
25984 + unsigned int maxdlci)
25986 + int num = fspTlv->baseTlv.length / MPLS_FSPFIXLEN;
25988 + fspTlv->baseTlv.length += MPLS_FSPFIXLEN;
25989 + fspTlv->lblRngList[num].flags.flags.res_min = resmin;
25990 + fspTlv->lblRngList[num].flags.flags.len = len;
25991 + fspTlv->lblRngList[num].flags.flags.minDlci = mindlci;
25992 + fspTlv->lblRngList[num].flags.flags.res_max = resmax;
25993 + fspTlv->lblRngList[num].flags.flags.maxDlci = maxdlci;
25994 + return MPLS_FSPFIXLEN;
25997 +int setupAspTlv(mplsLdpAspTlv_t * aspTlv, uint8_t merge, uint8_t direction)
25999 + aspTlv->baseTlv.flags.flags.tBit = MPLS_ASP_TLVTYPE;
26000 + aspTlv->baseTlv.flags.flags.uBit = 0;
26001 + aspTlv->baseTlv.flags.flags.fBit = 0;
26002 + aspTlv->flags.flags.dir = direction;
26003 + aspTlv->flags.flags.mergeType = merge;
26004 + aspTlv->baseTlv.length = 0;
26005 + return MPLS_TLVFIXLEN;
26008 +int setupFspTlv(mplsLdpFspTlv_t * fspTlv, uint8_t merge, uint8_t direction)
26010 + fspTlv->baseTlv.flags.flags.tBit = MPLS_FSP_TLVTYPE;
26011 + fspTlv->baseTlv.flags.flags.uBit = 0;
26012 + fspTlv->baseTlv.flags.flags.fBit = 0;
26013 + fspTlv->flags.flags.dir = direction;
26014 + fspTlv->flags.flags.mergeType = merge;
26015 + fspTlv->baseTlv.length = 0;
26016 + return MPLS_TLVFIXLEN;
26019 +int setupFecTlv(mplsLdpFecTlv_t * fecTlv)
26021 + fecTlv->baseTlv.flags.flags.tBit = MPLS_FEC_TLVTYPE;
26022 + fecTlv->baseTlv.flags.flags.uBit = 0;
26023 + fecTlv->baseTlv.flags.flags.fBit = 0;
26024 + fecTlv->baseTlv.length = 0;
26025 + fecTlv->wcElemExists = 0;
26026 + fecTlv->numberFecElements = 0;
26027 + return MPLS_TLVFIXLEN;
26031 +#if 0
26032 + mplsFecElement_t * createFecElemFromFecType(struct mpls_fec * fec)
26034 + mplsFecElement_t * fecElem =
26035 + (mplsFecElement_t *) malloc(sizeof(mplsFecElement_t));
26036 + fecElem->addressEl.type = MPLS_PREFIX_FEC;
26037 + fecElem->addressEl.addressFam = 1;
26038 + fecElem->addressEl.preLen = fec->len;
26039 + fecElem->addressEl.address = fec->prefix;
26040 + return fecElem;
26043 +mplsFecElement_t * createFecElemFromRoute(routeT * r)
26045 + mplsFecElement_t * fecElem =
26046 + (mplsFecElement_t *) malloc(sizeof(mplsFecElement_t));
26047 + memset(fecElem, 0, sizeof(mplsFecElement_t));
26048 + fecElem->addressEl.type = MPLS_PREFIX_FEC;
26049 + fecElem->addressEl.addressFam = 1;
26050 + fecElem->addressEl.preLen = r->len;
26051 + fecElem->addressEl.address = r->prefix;
26052 + return fecElem;
26056 +#endif /* */
26057 +int addFecElem2FecTlv(mplsLdpFecTlv_t * fecTlv, mplsFecElement_t * elem)
26059 + int num = fecTlv->numberFecElements;
26060 + int size = 0;
26062 + switch (elem->addressEl.type) {
26063 + case MPLS_PREFIX_FEC:
26064 + case MPLS_HOSTADR_FEC:
26065 + size = elem->addressEl.preLen / 8;
26066 + if (elem->addressEl.preLen % 8)
26067 + size++;
26068 + size += 4;
26069 + break;
26070 + case MPLS_CRLSP_FEC:
26071 + size = 4;
26072 + break;
26074 + fecTlv->baseTlv.length += size;
26075 + memcpy(&(fecTlv->fecElArray[num]), elem, sizeof(mplsFecElement_t));
26076 + fecTlv->fecElemTypes[num] = elem->addressEl.type;
26077 + fecTlv->numberFecElements++;
26078 + return size;
26082 +#if 0
26083 +void copyLabelType2MapLabelTlv(struct mpls_label *label,
26084 + mplsLdpLblMapMsg_t * lblMap)
26086 + switch (label->ml_type) {
26087 + case MPLS_LABEL_ATM:
26088 + lblMap->baseMsg.msgLength +=
26089 + setupAtmLblTlv(&(lblMap->atmLblTlv), 0, 0, label->u.ml_atm.mla_vpi,
26090 + label->u.ml_atm.mla_vci); lblMap->atmLblTlvExists = 1;
26091 + lblMap->genLblTlvExists = 0;
26092 + lblMap->frLblTlvExists = 0;
26093 + break;
26094 + case MPLS_LABEL_GEN:
26095 + lblMap->baseMsg.msgLength +=
26096 + setupGenLblTlv(&(lblMap->genLblTlv), label->u.ml_gen);
26097 + lblMap->atmLblTlvExists = 0;
26098 + lblMap->genLblTlvExists = 1;
26099 + lblMap->frLblTlvExists = 0;
26100 + break;
26101 + case MPLS_LABEL_FR:
26102 + lblMap->baseMsg.msgLength +=
26103 + setupFrLblTlv(&(lblMap->frLblTlv), 0, 0, label->u.ml_fr);
26104 + lblMap->atmLblTlvExists = 0;
26105 + lblMap->genLblTlvExists = 0;
26106 + lblMap->frLblTlvExists = 1;
26107 + break;
26108 + default:
26109 + LDP_PRINT(g->user_data, "invalid label type\n");
26110 + break;
26113 +void copyAtmLblTlv2MplsLabel(mplsLdpAtmLblTlv_t * atmLblTlv,
26114 + struct mpls_label *label)
26116 + label->ml_type = MPLS_LABEL_ATM;
26117 + label->u.ml_atm.mla_vpi = atmLblTlv->flags.flags.vpi;
26118 + label->u.ml_atm.mla_vci = atmLblTlv->vci;
26122 +#endif /* */
26124 +int setupAtmLblTlv(mplsLdpAtmLblTlv_t * atmLblTlv, int res, int v,
26125 + unsigned int vpi, unsigned int vci)
26127 + atmLblTlv->baseTlv.flags.flags.tBit = MPLS_ATMLBL_TLVTYPE;
26128 + atmLblTlv->baseTlv.flags.flags.uBit = 0;
26129 + atmLblTlv->baseTlv.flags.flags.fBit = 0;
26130 + atmLblTlv->baseTlv.length = MPLS_LBLFIXLEN;
26131 + atmLblTlv->flags.flags.res = res;
26132 + atmLblTlv->flags.flags.v = v;
26133 + atmLblTlv->flags.flags.vpi = vpi;
26134 + atmLblTlv->vci = vci;
26135 + return MPLS_LBLFIXLEN + MPLS_TLVFIXLEN;
26139 +#if 0
26140 +void copyFrLblTlv2MplsLabel(mplsLdpFrLblTlv_t * frLblTlv,
26141 + struct mpls_label *label)
26143 + label->ml_type = MPLS_LABEL_FR;
26144 + label->u.ml_fr = frLblTlv->flags.flags.dlci;
26148 +#endif /* */
26150 +int setupFrLblTlv(mplsLdpFrLblTlv_t * frLblTlv, int res, int len,
26151 + unsigned int dlci)
26153 + frLblTlv->baseTlv.flags.flags.tBit = MPLS_FRLBL_TLVTYPE;
26154 + frLblTlv->baseTlv.flags.flags.uBit = 0;
26155 + frLblTlv->baseTlv.flags.flags.fBit = 0;
26156 + frLblTlv->baseTlv.length = MPLS_LBLFIXLEN;
26157 + frLblTlv->flags.flags.res = res;
26158 + frLblTlv->flags.flags.len = len;
26159 + frLblTlv->flags.flags.dlci = dlci;
26160 + return MPLS_LBLFIXLEN + MPLS_TLVFIXLEN;
26164 +#if 0
26165 +void copyGenLblTlv2MplsLabel(mplsLdpGenLblTlv_t * genLblTlv,
26166 + struct mpls_label *label)
26168 + label->ml_type = MPLS_LABEL_GEN;
26169 + label->u.ml_gen = genLblTlv->label;
26173 +#endif /* */
26175 +int setupGenLblTlv(mplsLdpGenLblTlv_t * genLblTlv, int label)
26177 + genLblTlv->baseTlv.flags.flags.tBit = MPLS_GENLBL_TLVTYPE;
26178 + genLblTlv->baseTlv.flags.flags.uBit = 0;
26179 + genLblTlv->baseTlv.flags.flags.fBit = 0;
26180 + genLblTlv->baseTlv.length = MPLS_LBLFIXLEN;
26181 + genLblTlv->label = label;
26182 + return MPLS_LBLFIXLEN + MPLS_TLVFIXLEN;
26185 +int setupHopCountTlv(mplsLdpHopTlv_t * hopCountTlv, unsigned int hopCount)
26187 + hopCountTlv->baseTlv.flags.flags.tBit = MPLS_HOPCOUNT_TLVTYPE;
26188 + hopCountTlv->baseTlv.flags.flags.uBit = 0;
26189 + hopCountTlv->baseTlv.flags.flags.fBit = 0;
26190 + hopCountTlv->baseTlv.length = MPLS_HOPCOUNTFIXLEN;
26191 + hopCountTlv->hcValue = hopCount;
26192 + return MPLS_HOPCOUNTFIXLEN + MPLS_TLVFIXLEN;
26195 +int setupPathTlv(mplsLdpPathTlv_t * pathTlv)
26197 + pathTlv->baseTlv.flags.flags.tBit = MPLS_PATH_TLVTYPE;
26198 + pathTlv->baseTlv.flags.flags.uBit = 0;
26199 + pathTlv->baseTlv.flags.flags.fBit = 0;
26200 + pathTlv->baseTlv.length = 0;
26201 + return MPLS_TLVFIXLEN;
26204 +int addLsrId2PathTlv(mplsLdpPathTlv_t * pathTlv, unsigned int lsrId)
26206 + int num = pathTlv->baseTlv.length / sizeof(unsigned int);
26207 + pathTlv->baseTlv.length += sizeof(unsigned int);
26209 + pathTlv->lsrId[num] = lsrId;
26210 + return sizeof(unsigned int);
26213 +int setupAddrTlv(mplsLdpAdrTlv_t * addrTlv)
26215 + addrTlv->baseTlv.flags.flags.tBit = MPLS_ADDRLIST_TLVTYPE;
26216 + addrTlv->baseTlv.flags.flags.uBit = 0;
26217 + addrTlv->baseTlv.flags.flags.fBit = 0;
26218 + addrTlv->baseTlv.length = MPLS_ADDFAMFIXLEN;
26219 + addrTlv->addrFamily = 1;
26220 + return MPLS_TLVFIXLEN + MPLS_ADDFAMFIXLEN;
26223 +int addAddrElem2AddrTlv(mplsLdpAdrTlv_t * addrTlv, unsigned int addr)
26225 + int num = (addrTlv->baseTlv.length - MPLS_ADDFAMFIXLEN) / MPLS_IPv4LEN;
26227 + addrTlv->address[num] = addr;
26228 + addrTlv->baseTlv.length += MPLS_IPv4LEN;
26229 + return MPLS_IPv4LEN;
26232 +int setupStatusTlv(mplsLdpStatusTlv_t * statTlv, int fatal, int forward,
26233 + int status, unsigned int msgId, int msgType)
26235 + statTlv->baseTlv.flags.flags.tBit = MPLS_NOT_ST_TLVTYPE;
26236 + statTlv->baseTlv.flags.flags.uBit = 0;
26237 + statTlv->baseTlv.flags.flags.fBit = 0;
26238 + statTlv->baseTlv.length = MPLS_STATUSFIXLEN;
26239 + statTlv->flags.flags.error = fatal;
26240 + statTlv->flags.flags.forward = forward;
26241 + statTlv->flags.flags.status = status;
26242 + statTlv->msgId = msgId;
26243 + statTlv->msgType = msgType;
26244 + return MPLS_STATUSFIXLEN + MPLS_TLVFIXLEN;
26247 +int setupExStatusTlv(mplsLdpExStatusTlv_t * exStatus, unsigned int value)
26249 + exStatus->baseTlv.flags.flags.tBit = MPLS_NOT_ES_TLVTYPE;
26250 + exStatus->baseTlv.flags.flags.uBit = 0;
26251 + exStatus->baseTlv.flags.flags.fBit = 0;
26252 + exStatus->baseTlv.length = MPLS_EXSTATUSLEN;
26253 + exStatus->value = value;
26254 + return MPLS_EXSTATUSLEN + MPLS_TLVFIXLEN;
26257 +int setupRetPduTlv(mplsLdpRetPduTlv_t * retPduTvl, unsigned int len,
26258 + mplsLdpHeader_t * hdr, void *data)
26260 + retPduTvl->baseTlv.flags.flags.tBit = MPLS_NOT_RP_TLVTYPE;
26261 + retPduTvl->baseTlv.flags.flags.uBit = 0;
26262 + retPduTvl->baseTlv.flags.flags.fBit = 0;
26263 + retPduTvl->baseTlv.length = MPLS_LDP_HDRSIZE + len;
26264 + memcpy(&(retPduTvl->headerTlv), hdr, MPLS_LDP_HDRSIZE);
26265 + memcpy(retPduTvl->data, data, len);
26266 + return MPLS_LDP_HDRSIZE + len + MPLS_TLVFIXLEN;
26269 +int setupRetMsgTlv(mplsLdpRetMsgTlv_t * retMsgTlv, unsigned type,
26270 + unsigned len, void *data)
26272 + retMsgTlv->baseTlv.flags.flags.tBit = MPLS_NOT_RM_TLVTYPE;
26273 + retMsgTlv->baseTlv.flags.flags.uBit = 0;
26274 + retMsgTlv->baseTlv.flags.flags.fBit = 0;
26275 + retMsgTlv->baseTlv.length = len;
26276 + retMsgTlv->msgType = type;
26277 + retMsgTlv->msgLength = 4 + len;
26278 + memcpy(retMsgTlv->data, data, len);
26279 + return 4 + len + MPLS_TLVFIXLEN;
26282 +int setupLspidTlv(mplsLdpLspIdTlv_t * lspidTlv, int res,
26283 + unsigned int localCrlspId, unsigned int routerId)
26285 + lspidTlv->baseTlv.flags.flags.tBit = MPLS_LSPID_TLVTYPE;
26286 + lspidTlv->baseTlv.flags.flags.uBit = 0;
26287 + lspidTlv->baseTlv.flags.flags.fBit = 0;
26288 + lspidTlv->baseTlv.length = MPLS_LSPIDTLV_FIXLEN;
26289 + lspidTlv->res = res;
26290 + lspidTlv->localCrlspId = localCrlspId;
26291 + lspidTlv->routerId = routerId;
26292 + return MPLS_LSPIDTLV_FIXLEN + MPLS_TLVFIXLEN;
26295 +int setupTrafficTlv(mplsLdpTrafficTlv_t * trafficTlv, unsigned char freq,
26296 + unsigned char res, unsigned char weight, float pdr, float pbs, float cdr,
26297 + float cbs, float ebs)
26299 + trafficTlv->baseTlv.flags.flags.tBit = MPLS_TRAFFIC_TLVTYPE;
26300 + trafficTlv->baseTlv.flags.flags.uBit = 0;
26301 + trafficTlv->baseTlv.flags.flags.fBit = 0;
26302 + trafficTlv->baseTlv.length = 0;
26303 + trafficTlv->flags.flags.res = 0;
26304 + trafficTlv->flags.flags.f6Bit = 0;
26305 + trafficTlv->flags.flags.f5Bit = 0;
26306 + trafficTlv->flags.flags.f4Bit = 0;
26307 + trafficTlv->flags.flags.f3Bit = 0;
26308 + trafficTlv->flags.flags.f2Bit = 0;
26309 + trafficTlv->flags.flags.f1Bit = 0;
26310 + trafficTlv->freq = freq;
26311 + trafficTlv->res = res;
26312 + trafficTlv->weight = weight;
26313 + trafficTlv->pdr.pdr = pdr;
26314 + trafficTlv->pbs.pbs = pbs;
26315 + trafficTlv->cdr.cdr = cdr;
26316 + trafficTlv->cbs.cbs = cbs;
26317 + trafficTlv->ebs.ebs = ebs;
26318 + return MPLS_TLVFIXLEN;
26321 +int setupLblMsgIdTlv(mplsLdpLblMsgIdTlv_t * lblMsgIdTlv, unsigned int msgId)
26323 + lblMsgIdTlv->baseTlv.flags.flags.tBit = MPLS_REQMSGID_TLVTYPE;
26324 + lblMsgIdTlv->baseTlv.flags.flags.uBit = 0;
26325 + lblMsgIdTlv->baseTlv.flags.flags.fBit = 0;
26326 + lblMsgIdTlv->baseTlv.length = MPLS_MSGIDFIXLEN;
26327 + lblMsgIdTlv->msgId = msgId;
26328 + return MPLS_MSGIDFIXLEN + MPLS_TLVFIXLEN;
26330 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_pdu_setup.h quagga-mpls/ldpd/ldp_pdu_setup.h
26331 --- quagga/ldpd/ldp_pdu_setup.h 1969-12-31 18:00:00.000000000 -0600
26332 +++ quagga-mpls/ldpd/ldp_pdu_setup.h 2006-08-09 21:56:14.000000000 -0500
26333 @@ -0,0 +1,89 @@
26336 + * Copyright (C) James R. Leu 2000
26337 + * jleu@mindspring.com
26339 + * This software is covered under the LGPL, for more
26340 + * info check out http://www.gnu.org/copyleft/lgpl.html
26341 + */
26343 +#ifndef _PDU_SETUP_
26344 +#define _PDU_SETUP_
26346 +#include "ldp_struct.h"
26347 +#include "ldp_nortel.h"
26348 + void setBaseMsgId(mplsLdpMsg_t * baseMsg, unsigned int msgId);
26349 + void setupBaseMsg(mplsLdpMsg_t * baseMsg, unsigned int type, int uBit,
26351 + unsigned int msgId);
26352 + int setupChpTlv(mplsLdpChpTlv_t * chpTlv, int target, int request, int res,
26354 + int holdTime);
26355 + int setupPinningTlv(mplsLdpPinningTlv_t * pinningTlv, int pBit, int res);
26356 + int setupResClassTlv(mplsLdpResClsTlv_t * resClsTlv, unsigned int rsCls);
26357 + int setupPreemptTlv(mplsLdpPreemptTlv_t * preemptTlv, unsigned char setPrio,
26358 + unsigned char holdPrio, unsigned short res);
26359 + int addErHop2ErHopTvl(mplsLdpErTlv_t * erHopTlv, mplsLdpErHop_t * erHop,
26360 + unsigned short type); int setupErHopTlv(mplsLdpErTlv_t * erHopTlv);
26361 + int setupTrAddrTlv(mplsLdpTrAdrTlv_t * trAddrTlv, unsigned int trAddr);
26362 + int setupCsnTlv(mplsLdpCsnTlv_t * csnTlv, unsigned int confSeqNum);
26363 + int setupCspTlv(mplsLdpCspTlv_t * cspTlv, uint16_t keepalive,
26364 + uint8_t adv_discp, uint8_t loop, uint8_t pvl, uint16_t mtu,
26365 + uint32_t remote_lsraddr, uint16_t remote_labelspace, uint32_t res);
26366 + int addLblRng2AspTlv(mplsLdpAspTlv_t * aspTlv, unsigned int minvpi,
26367 + unsigned int minvci, unsigned int maxvpi, unsigned int maxvci);
26368 + int addLblRng2FspTlv(mplsLdpFspTlv_t * fspTlv, unsigned int resmin,
26369 + unsigned int len, unsigned int mindlci, unsigned int resmax,
26371 + unsigned int maxdlci);
26372 + int setupAspTlv(mplsLdpAspTlv_t * aspTlv, uint8_t merge, uint8_t direction);
26373 + int setupFspTlv(mplsLdpFspTlv_t * fspTlv, uint8_t merge, uint8_t direction);
26374 + int setupFecTlv(mplsLdpFecTlv_t * fecTlv);
26377 +#if 0
26378 + mplsFecElement_t * createFecElemFromFecType(struct mpls_fec *fec);
26380 + mplsFecElement_t * createFecElemFromRoute(routeT * r);
26381 + void copyLabelType2MapLabelTlv(struct mpls_label *label,
26383 + mplsLdpLblMapMsg_t * lblMap);
26384 + void copyAtmLblTlv2MplsLabel(mplsLdpAtmLblTlv_t * atmLblTlv,
26386 + struct mpls_label *label);
26387 + void copyFrLblTlv2MplsLabel(mplsLdpFrLblTlv_t * frLblTlv,
26389 + struct mpls_label *label);
26390 + void copyGenLblTlv2MplsLabel(mplsLdpGenLblTlv_t * genLblTlv,
26392 + struct mpls_label *label);
26393 +#endif /* */
26394 +int addFecElem2FecTlv(mplsLdpFecTlv_t * fecTlv, mplsFecElement_t * elem);
26395 + int setupAtmLblTlv(mplsLdpAtmLblTlv_t * atmLblTlv, int res, int v,
26396 + unsigned int vpi, unsigned int vci);
26397 + int setupFrLblTlv(mplsLdpFrLblTlv_t * frLblTlv, int res, int len,
26399 + unsigned int dlci);
26400 + int setupGenLblTlv(mplsLdpGenLblTlv_t * genLblTlv, int label);
26401 + int setupHopCountTlv(mplsLdpHopTlv_t * hopCountTlv, unsigned int hopCount);
26402 + int setupPathTlv(mplsLdpPathTlv_t * pathTlv);
26403 + int addLsrId2PathTlv(mplsLdpPathTlv_t * pathTlv, unsigned int lsrId);
26404 + int setupAddrTlv(mplsLdpAdrTlv_t * addrTlv);
26405 + int addAddrElem2AddrTlv(mplsLdpAdrTlv_t * addrTlv, unsigned int addr);
26406 + int setupStatusTlv(mplsLdpStatusTlv_t * statTlv, int fatal, int forward,
26407 + int status, unsigned int msgId, int msgType);
26408 + int setupExStatusTlv(mplsLdpExStatusTlv_t * exStatus, unsigned int value);
26409 + int setupRetPduTlv(mplsLdpRetPduTlv_t * retPduTvl, unsigned int len,
26410 + mplsLdpHeader_t * hdr, void *data);
26411 + int setupRetMsgTlv(mplsLdpRetMsgTlv_t * retMsgTlv, unsigned type, unsigned len,
26413 + void *data);
26414 + int setupLspidTlv(mplsLdpLspIdTlv_t * lspidTlv, int res,
26415 + unsigned int localCrlspId, unsigned int routerId);
26416 + int setupTrafficTlv(mplsLdpTrafficTlv_t * trafficTlv, unsigned char freq,
26417 + unsigned char res, unsigned char weight, float pdr, float pbs, float cdr,
26418 + float cbs, float ebs);
26419 + int setupLblMsgIdTlv(mplsLdpLblMsgIdTlv_t * lblMsgIdTlv, unsigned int msgId);
26422 +#endif /* */
26423 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_peer.c quagga-mpls/ldpd/ldp_peer.c
26424 --- quagga/ldpd/ldp_peer.c 1969-12-31 18:00:00.000000000 -0600
26425 +++ quagga-mpls/ldpd/ldp_peer.c 2006-08-09 21:56:12.000000000 -0500
26426 @@ -0,0 +1,222 @@
26429 + * Copyright (C) James R. Leu 2000
26430 + * jleu@mindspring.com
26432 + * This software is covered under the LGPL, for more
26433 + * info check out http://www.gnu.org/copyleft/lgpl.html
26434 + */
26436 +#include <stdlib.h>
26437 +#include <sys/socket.h>
26438 +#include "ldp_struct.h"
26439 +#include "ldp_entity.h"
26440 +#include "ldp_peer.h"
26441 +#include "ldp_hello.h"
26442 +#include "ldp_buf.h"
26443 +#include "ldp_mesg.h"
26445 +#include "mpls_assert.h"
26446 +#include "mpls_fib_impl.h"
26447 +#include "mpls_ifmgr_impl.h"
26448 +#include "mpls_lock_impl.h"
26449 +#include "mpls_timer_impl.h"
26450 +#include "mpls_mm_impl.h"
26451 +#include "mpls_trace_impl.h"
26453 +uint32_t _ldp_sub_entity_next_index = 1;
26455 +void ldp_peer_retry_callback(mpls_timer_handle timer, void *extra,
26456 + mpls_cfg_handle handle)
26458 + ldp_peer *p = (ldp_peer *) extra;
26459 + ldp_global *g = (ldp_global*)handle;
26461 + LDP_ENTER(g->user_data, "ldp_peer_retry_callback");
26463 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_TIMER,
26464 + "Peer Retry Timer fired: peer(%d)\n", p->index);
26466 + mpls_lock_get(g->global_lock);
26468 + /* JLEU: should I hold a copy to make sure this doens't fail? */
26469 + ldp_peer_retry_stop(g, p);
26470 + if (ldp_peer_startup(g, p) == MPLS_FAILURE) {
26471 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ERROR,
26472 + "Peer startup retry failure: peer (%d)\n", p->index);
26475 + mpls_lock_release(g->global_lock);
26477 + LDP_EXIT(g->user_data, "ldp_peer_retry_callback");
26480 +ldp_peer *ldp_peer_create()
26482 + ldp_peer *p = (ldp_peer *) mpls_malloc(sizeof(ldp_peer));
26484 + if (p) {
26485 + memset(p, 0, sizeof(ldp_peer));
26486 + MPLS_REFCNT_INIT(p, 0);
26487 + MPLS_LIST_ELEM_INIT(p, _global);
26488 + p->label_space = -1;
26489 + p->tx_buffer = ldp_buf_create(MPLS_PDUMAXLEN);
26490 + p->tx_message = ldp_mesg_create();
26491 + p->index = _ldp_peer_get_next_index();
26493 + p->oper_state = MPLS_OPER_DOWN;
26494 + p->target_role = LDP_ACTIVE;
26496 + return p;
26499 +void ldp_peer_delete(ldp_peer * p)
26501 + // LDP_PRINT(g->user_data,"peer delete\n");
26502 + MPLS_REFCNT_ASSERT(p, 0);
26503 + mpls_free(p->tx_buffer);
26504 + mpls_free(p->tx_message);
26505 + mpls_free(p);
26508 +mpls_return_enum ldp_peer_startup(ldp_global * g, ldp_peer * p)
26510 + ldp_entity *e = NULL;
26512 + MPLS_ASSERT(p != NULL && ((e = p->entity) != NULL));
26514 + LDP_ENTER(g->user_data, "ldp_peer_startup");
26516 + p->dest.port = e->remote_udp_port;
26518 + if (p->target_role == LDP_ACTIVE) {
26519 + if (ldp_hello_send(g, e) == MPLS_FAILURE) {
26520 + goto ldp_peer_startup_retry;
26524 + p->oper_state = MPLS_OPER_UP;
26526 + LDP_EXIT(g->user_data, "ldp_peer_startup");
26528 + return MPLS_SUCCESS;
26530 +ldp_peer_startup_retry:
26532 + /* start a timer which will retry peer startup */
26533 + MPLS_REFCNT_HOLD(p);
26534 + p->oper_state = MPLS_OPER_DOWN;
26535 + p->no_route_to_peer_timer = mpls_timer_create(g->timer_handle, MPLS_UNIT_SEC,
26536 + g->no_route_to_peer_time, (void *)p, g, ldp_peer_retry_callback);
26538 + if (mpls_timer_handle_verify(g->timer_handle, p->no_route_to_peer_timer) ==
26539 + MPLS_BOOL_FALSE) {
26540 + MPLS_REFCNT_RELEASE(p, ldp_peer_delete);
26541 + LDP_EXIT(g->user_data, "ldp_peer_startup-error");
26542 + return MPLS_FAILURE;
26544 + mpls_timer_start(g->timer_handle, p->no_route_to_peer_timer, MPLS_TIMER_ONESHOT);
26546 + LDP_EXIT(g->user_data, "ldp_peer_startup");
26548 + return MPLS_SUCCESS;
26551 +void ldp_peer_retry_stop(ldp_global * g, ldp_peer * p)
26553 + MPLS_ASSERT(p != NULL);
26555 + LDP_ENTER(g->user_data, "ldp_peer_retry_stop");
26557 + if (mpls_timer_handle_verify(g->timer_handle, p->no_route_to_peer_timer) ==
26558 + MPLS_BOOL_TRUE) {
26559 + mpls_timer_stop(g->timer_handle, p->no_route_to_peer_timer);
26560 + mpls_timer_delete(g->timer_handle, p->no_route_to_peer_timer);
26561 + p->no_route_to_peer_timer = 0;
26562 + MPLS_REFCNT_RELEASE(p, ldp_peer_delete);
26563 + MPLS_ASSERT(p != NULL);
26566 + LDP_EXIT(g->user_data, "ldp_peer_retry_stop");
26569 +void ldp_peer_send_stop(ldp_global * g, ldp_peer * p)
26571 + ldp_entity *e = NULL;
26573 + MPLS_ASSERT(p != NULL && (e = p->entity) != NULL);
26575 + LDP_ENTER(g->user_data, "ldp_peer_send_stop");
26577 + if (mpls_timer_handle_verify(g->timer_handle, p->hellotime_send_timer) ==
26578 + MPLS_BOOL_TRUE) {
26579 + mpls_timer_stop(g->timer_handle, p->hellotime_send_timer);
26580 + mpls_timer_delete(g->timer_handle, p->hellotime_send_timer);
26581 + p->hellotime_send_timer_duration = 0;
26582 + p->hellotime_send_timer = 0;
26583 + MPLS_REFCNT_RELEASE(e, ldp_entity_delete);
26584 + MPLS_ASSERT(e != NULL);
26586 + if (p->hello != NULL) {
26587 + ldp_mesg_delete(p->hello);
26588 + p->hello = NULL;
26591 + LDP_EXIT(g->user_data, "ldp_peer_send_stop");
26594 +mpls_return_enum ldp_peer_shutdown(ldp_global * g, ldp_peer * p)
26596 + LDP_ENTER(g->user_data, "ldp_peer_shutdown");
26598 + p->oper_state = MPLS_OPER_DOWN;
26599 + ldp_peer_send_stop(g, p);
26600 + ldp_peer_retry_stop(g, p);
26602 + LDP_EXIT(g->user_data, "ldp_peer_shutdown");
26603 + return MPLS_SUCCESS;
26606 +mpls_bool ldp_peer_is_active(ldp_peer * p)
26608 + if (p && p->entity && p->entity->admin_state == MPLS_ADMIN_ENABLE)
26609 + return MPLS_BOOL_TRUE;
26611 + return MPLS_BOOL_FALSE;
26614 +mpls_return_enum _ldp_peer_add_entity(ldp_peer * p, ldp_entity * e)
26616 + if (p && e) {
26617 + MPLS_REFCNT_HOLD(e);
26618 + p->entity = e;
26619 + return MPLS_SUCCESS;
26621 + return MPLS_FAILURE;
26624 +mpls_return_enum _ldp_peer_del_entity(ldp_peer * p)
26626 + if (p && p->entity) {
26627 + MPLS_REFCNT_RELEASE(p->entity, ldp_entity_delete);
26628 + p->entity = NULL;
26629 + return MPLS_SUCCESS;
26631 + return MPLS_FAILURE;
26634 +ldp_entity *ldp_peer_get_entity(ldp_peer * p)
26636 + return p->entity;
26639 +uint32_t _ldp_peer_get_next_index()
26641 + uint32_t retval = _ldp_sub_entity_next_index;
26643 + _ldp_sub_entity_next_index++;
26644 + if (retval > _ldp_sub_entity_next_index) {
26645 + _ldp_sub_entity_next_index = 1;
26647 + return retval;
26649 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_peer.h quagga-mpls/ldpd/ldp_peer.h
26650 --- quagga/ldpd/ldp_peer.h 1969-12-31 18:00:00.000000000 -0600
26651 +++ quagga-mpls/ldpd/ldp_peer.h 2006-08-09 21:56:11.000000000 -0500
26652 @@ -0,0 +1,29 @@
26655 + * Copyright (C) James R. Leu 2000
26656 + * jleu@mindspring.com
26658 + * This software is covered under the LGPL, for more
26659 + * info check out http://www.gnu.org/copyleft/lgpl.html
26660 + */
26662 +#ifndef _LDP_PEER_H_
26663 +#define _LDP_PEER_H_
26665 +#include "ldp_struct.h"
26667 +extern ldp_peer *ldp_peer_create();
26668 +extern void ldp_peer_delete(ldp_peer * p);
26669 +extern mpls_return_enum ldp_peer_startup(ldp_global * g, ldp_peer * p);
26670 +extern mpls_return_enum ldp_peer_shutdown(ldp_global * g, ldp_peer * p);
26671 +extern mpls_bool ldp_peer_is_active(ldp_peer * p);
26672 +extern mpls_return_enum _ldp_peer_add_entity(ldp_peer * p, ldp_entity * e);
26673 +extern mpls_return_enum _ldp_peer_del_entity(ldp_peer * p);
26674 +extern ldp_entity *ldp_peer_get_entity(ldp_peer * p);
26675 +extern uint32_t _ldp_peer_get_next_index();
26676 +extern void ldp_peer_retry_stop(ldp_global * g, ldp_peer * p);
26677 +extern void ldp_peer_send_stop(ldp_global * g, ldp_peer * p);
26678 +extern void ldp_peer_retry_callback(mpls_timer_handle timer, void *extra,
26679 + mpls_cfg_handle g);
26681 +#endif
26682 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_remote_peer.c quagga-mpls/ldpd/ldp_remote_peer.c
26683 --- quagga/ldpd/ldp_remote_peer.c 1969-12-31 18:00:00.000000000 -0600
26684 +++ quagga-mpls/ldpd/ldp_remote_peer.c 2006-08-09 22:02:25.000000000 -0500
26685 @@ -0,0 +1,129 @@
26686 +#include <zebra.h>
26687 +#include "memory.h"
26689 +#include "ldp.h"
26690 +#include "ldp_cfg.h"
26691 +#include "ldp_struct.h"
26692 +#include "mpls_compare.h"
26693 +#include "ldp_remote_peer.h"
26695 +struct ldp_remote_peer *ldp_remote_peer_find(struct ldp *ldp,
26696 + struct mpls_dest *dest) {
26697 + struct ldp_remote_peer *rp;
26698 + struct listnode *ln;
26700 + for(ALL_LIST_ELEMENTS_RO(ldp->peer_list,ln, rp)) {
26701 + rp->peer.dest.if_handle = 0;
26702 + dest->if_handle = 0;
26703 + if (!mpls_dest_compare(&rp->peer.dest,dest)) {
26704 + return rp;
26707 + return NULL;
26710 +struct ldp_remote_peer *ldp_remote_peer_new(struct ldp *ldp) {
26711 + struct ldp_remote_peer *rp;
26713 + rp = XMALLOC(MTYPE_LDP, sizeof(struct ldp_remote_peer));
26714 + memset(rp, 0, sizeof(struct ldp_remote_peer));
26715 + rp->ldp = ldp;
26717 + rp->admin_up = MPLS_BOOL_TRUE;
26718 + ldp_entity_set_defaults(&rp->entity);
26720 + return rp;
26723 +void ldp_remote_peer_free(struct ldp_remote_peer *rp) {
26724 + XFREE(MTYPE_LDP, rp);
26727 +void ldp_remote_peer_create(struct ldp_remote_peer *rp,
26728 + struct mpls_dest *dest) {
26729 + struct in_addr addr;
26730 + char *dest_name;
26732 + addr.s_addr = htonl(dest->addr.u.ipv4);
26733 + dest_name = inet_ntoa(addr);
26734 + strncpy(rp->peer.peer_name,dest_name,IFNAMSIZ);
26735 + rp->peer.label_space = 0;
26736 + memcpy(&rp->peer.dest,dest,sizeof(struct mpls_dest));
26738 + ldp_cfg_peer_set(rp->ldp->h, &rp->peer, LDP_CFG_ADD |
26739 + LDP_IF_CFG_LABEL_SPACE | LDP_PEER_CFG_DEST_ADDR | LDP_PEER_CFG_PEER_NAME);
26741 + rp->entity.sub_index = rp->peer.index;
26742 + rp->entity.entity_type = LDP_INDIRECT;
26743 + rp->entity.admin_state = MPLS_OPER_DOWN;
26744 + rp->entity.transport_address.type = MPLS_FAMILY_NONE;
26746 + ldp_cfg_entity_set(rp->ldp->h, &rp->entity,
26747 + LDP_CFG_ADD | LDP_ENTITY_CFG_SUB_INDEX |
26748 + LDP_ENTITY_CFG_ADMIN_STATE | LDP_ENTITY_CFG_TRANS_ADDR);
26750 + ldp_cfg_entity_get(rp->ldp->h, &rp->entity, 0xFFFFFFFF);
26751 + ldp_cfg_peer_get(rp->ldp->h, &rp->peer, 0xFFFFFFFF);
26753 + ldp_remote_peer_admin_state_finish(rp);
26756 +void ldp_remote_peer_delete(struct ldp_remote_peer *rp) {
26757 + rp->entity.admin_state = MPLS_OPER_DOWN;
26759 + if (rp->ldp) {
26760 + ldp_remote_peer_admin_state_start(rp);
26761 + ldp_cfg_entity_set(rp->ldp->h, &rp->entity, LDP_CFG_DEL);
26762 + ldp_cfg_peer_set(rp->ldp->h, &rp->peer, LDP_CFG_DEL);
26764 + rp->entity.index = 0;
26765 + rp->peer.index = 0;
26768 +int ldp_remote_peer_startup(struct ldp_remote_peer *rp) {
26769 + if (!rp->peer.index) {
26770 + return MPLS_FAILURE;
26773 + rp->entity.admin_state = MPLS_OPER_UP;
26774 + ldp_cfg_entity_set(rp->ldp->h, &rp->entity, LDP_ENTITY_CFG_ADMIN_STATE);
26776 + return MPLS_SUCCESS;
26779 +int ldp_remote_peer_shutdown(struct ldp_remote_peer *rp) {
26780 + if (!rp->peer.index) {
26781 + return MPLS_FAILURE;
26784 + rp->entity.admin_state = MPLS_ADMIN_DISABLE;
26785 + ldp_cfg_entity_set(rp->ldp->h, &rp->entity, LDP_ENTITY_CFG_ADMIN_STATE);
26787 + return MPLS_SUCCESS;
26790 +int ldp_remote_peer_admin_state_start(struct ldp_remote_peer *rp) {
26791 + if (rp->admin_up == MPLS_BOOL_TRUE) {
26792 + return ldp_remote_peer_shutdown(rp);
26794 + return MPLS_SUCCESS;
26797 +int ldp_remote_peer_admin_state_finish(struct ldp_remote_peer *rp) {
26798 + if (rp->admin_up == MPLS_BOOL_TRUE) {
26799 + return ldp_remote_peer_startup(rp);
26801 + return MPLS_SUCCESS;
26804 +void ldp_remote_peer_up(struct ldp_remote_peer *rp) {
26805 + if (rp->ldp && rp->admin_up == MPLS_BOOL_TRUE) {
26806 + ldp_remote_peer_startup(rp);
26810 +void ldp_remote_peer_down(struct ldp_remote_peer *rp) {
26811 + if (rp->ldp && rp->admin_up == MPLS_BOOL_TRUE) {
26812 + ldp_remote_peer_shutdown(rp);
26815 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_remote_peer.h quagga-mpls/ldpd/ldp_remote_peer.h
26816 --- quagga/ldpd/ldp_remote_peer.h 1969-12-31 18:00:00.000000000 -0600
26817 +++ quagga-mpls/ldpd/ldp_remote_peer.h 2006-08-09 22:02:26.000000000 -0500
26818 @@ -0,0 +1,28 @@
26819 +#ifndef LDP_REMOTE_PEER_H
26820 +#define LDP_REMOTE_PEER_H
26822 +#include "ldp_struct.h"
26824 +struct ldp_remote_peer {
26825 + struct ldp *ldp;
26826 + ldp_entity entity;
26827 + ldp_peer peer;
26828 + mpls_bool admin_up;
26831 +struct ldp_remote_peer *ldp_remote_peer_find(struct ldp*, struct mpls_dest*);
26832 +struct ldp_remote_peer *ldp_remote_peer_new(struct ldp *ldp);
26833 +void ldp_remote_peer_free(struct ldp_remote_peer *rp);
26835 +void ldp_remote_peer_up(struct ldp_remote_peer *rp);
26836 +void ldp_remote_peer_down(struct ldp_remote_peer *rp);
26838 +int ldp_remote_peer_startup(struct ldp_remote_peer *rp);
26839 +int ldp_remote_peer_shutdown(struct ldp_remote_peer *rp);
26841 +void ldp_remote_peer_create(struct ldp_remote_peer*, struct mpls_dest*);
26842 +void ldp_remote_peer_delete(struct ldp_remote_peer *rp);
26843 +int ldp_remote_peer_admin_state_start(struct ldp_remote_peer *rp);
26844 +int ldp_remote_peer_admin_state_finish(struct ldp_remote_peer *rp);
26846 +#endif
26847 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_resource.c quagga-mpls/ldpd/ldp_resource.c
26848 --- quagga/ldpd/ldp_resource.c 1969-12-31 18:00:00.000000000 -0600
26849 +++ quagga-mpls/ldpd/ldp_resource.c 2006-08-09 21:56:14.000000000 -0500
26850 @@ -0,0 +1,78 @@
26853 + * Copyright (C) James R. Leu 2001
26854 + * jleu@mindspring.com
26856 + * This software is covered under the LGPL, for more
26857 + * info check out http://www.gnu.org/copyleft/lgpl.html
26858 + */
26860 +#include "ldp_struct.h"
26861 +#include "ldp_resource.h"
26862 +#include "ldp_tunnel.h"
26864 +#include "mpls_assert.h"
26865 +#include "mpls_mm_impl.h"
26866 +#include "mpls_trace_impl.h"
26868 +static uint32_t _ldp_resource_next_index = 1;
26870 +ldp_resource *ldp_resource_create()
26872 + ldp_resource *r = (ldp_resource *) mpls_malloc(sizeof(ldp_resource));
26874 + if (r) {
26875 + memset(r, 0, sizeof(ldp_resource));
26876 + MPLS_REFCNT_INIT(r, 0);
26877 + MPLS_LIST_ELEM_INIT(r, _global);
26879 + r->index = _ldp_resource_get_next_index();
26881 + return r;
26884 +void ldp_resource_delete(ldp_resource * r)
26886 + // LDP_PRINT(g->user_data,"resource delete\n");
26887 + MPLS_REFCNT_ASSERT(r, 0);
26888 + mpls_free(r);
26891 +uint32_t _ldp_resource_get_next_index()
26893 + uint32_t retval = _ldp_resource_next_index;
26895 + _ldp_resource_next_index++;
26896 + if (retval > _ldp_resource_next_index) {
26897 + _ldp_resource_next_index = 1;
26899 + return retval;
26902 +mpls_return_enum _ldp_resource_add_tunnel(ldp_resource * r, ldp_tunnel * t)
26904 + if (r && t) {
26905 + MPLS_REFCNT_HOLD(t);
26906 + r->tunnel = t;
26907 + return MPLS_SUCCESS;
26909 + return MPLS_FAILURE;
26912 +mpls_return_enum _ldp_resource_del_tunnel(ldp_resource * r)
26914 + if (r && r->tunnel) {
26915 + MPLS_REFCNT_RELEASE(r->tunnel, ldp_tunnel_delete);
26916 + r->tunnel = NULL;
26917 + return MPLS_SUCCESS;
26919 + return MPLS_FAILURE;
26922 +mpls_bool ldp_resource_in_use(ldp_resource * r)
26924 + if (r->tunnel && (r->tunnel->admin_state == MPLS_ADMIN_ENABLE)) {
26925 + return MPLS_BOOL_TRUE;
26927 + return MPLS_BOOL_FALSE;
26929 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_resource.h quagga-mpls/ldpd/ldp_resource.h
26930 --- quagga/ldpd/ldp_resource.h 1969-12-31 18:00:00.000000000 -0600
26931 +++ quagga-mpls/ldpd/ldp_resource.h 2006-08-09 21:56:11.000000000 -0500
26932 @@ -0,0 +1,26 @@
26935 + * Copyright (C) James R. Leu 2001
26936 + * jleu@mindspring.com
26938 + * This software is covered under the LGPL, for more
26939 + * info check out http://www.gnu.org/copyleft/lgpl.html
26940 + */
26942 +#ifndef _LDP_RESOURCE_H_
26943 +#define _LDP_RESOURCE_H_
26945 +#include "ldp_struct.h"
26947 +extern ldp_resource *ldp_resource_create();
26948 +extern void ldp_resource_delete(ldp_resource * r);
26949 +extern uint32_t _ldp_resource_get_next_index();
26951 +extern mpls_return_enum _ldp_resource_add_tunnel(ldp_resource * r,
26953 + ldp_tunnel * t);
26954 +extern mpls_return_enum _ldp_resource_del_tunnel(ldp_resource * r);
26956 +extern mpls_bool ldp_resource_in_use(ldp_resource * r);
26958 +#endif
26959 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_session.c quagga-mpls/ldpd/ldp_session.c
26960 --- quagga/ldpd/ldp_session.c 1969-12-31 18:00:00.000000000 -0600
26961 +++ quagga-mpls/ldpd/ldp_session.c 2008-03-24 20:21:15.000000000 -0500
26962 @@ -0,0 +1,753 @@
26965 + * Copyright (C) James R. Leu 2000
26966 + * jleu@mindspring.com
26968 + * This software is covered under the LGPL, for more
26969 + * info check out http://www.gnu.org/copyleft/lgpl.html
26970 + */
26972 +#include <stdlib.h>
26973 +#include "ldp_struct.h"
26974 +#include "ldp_outlabel.h"
26975 +#include "ldp_session.h"
26976 +#include "ldp_entity.h"
26977 +#include "ldp_inlabel.h"
26978 +#include "ldp_outlabel.h"
26979 +#include "ldp_addr.h"
26980 +#include "ldp_attr.h"
26981 +#include "ldp_adj.h"
26982 +#include "ldp_mesg.h"
26983 +#include "ldp_buf.h"
26984 +#include "ldp_inet_addr.h"
26985 +#include "ldp_global.h"
26986 +#include "ldp_state_machine.h"
26987 +#include "ldp_label_rel_with.h"
26988 +#include "ldp_label_request.h"
26989 +#include "ldp_label_mapping.h"
26991 +#include "mpls_refcnt.h"
26992 +#include "mpls_assert.h"
26993 +#include "mpls_mm_impl.h"
26994 +#include "mpls_timer_impl.h"
26995 +#include "mpls_socket_impl.h"
26996 +#include "mpls_trace_impl.h"
26997 +#include "mpls_ifmgr_impl.h"
26998 +#include "mpls_policy_impl.h"
26999 +#include "mpls_lock_impl.h"
27001 +static uint32_t _ldp_session_next_index = 1;
27003 +mpls_return_enum ldp_session_attempt_setup(ldp_global *g, ldp_session *s);
27004 +mpls_return_enum ldp_session_backoff_stop(ldp_global * g, ldp_session * s);
27006 +static void ldp_session_backoff_callback(mpls_timer_handle timer, void *extra,
27007 + mpls_cfg_handle handle)
27009 + ldp_session *s = (ldp_session *)extra;
27010 + ldp_global *g = (ldp_global*)handle;
27012 + LDP_ENTER(g->user_data, "ldp_session_backoff");
27014 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_TIMER,
27015 + "Session Backoff Timer fired: session(%s)\n", s->session_name);
27017 + mpls_lock_get(g->global_lock);
27019 + s->backoff_timer = 0;
27021 + if (s->oper_role == LDP_ACTIVE) {
27022 + if (ldp_session_attempt_setup(g, s) != MPLS_SUCCESS) {
27023 + s->backoff += g->backoff_step;
27024 + s->backoff_timer = timer;
27025 + mpls_timer_start(g->timer_handle, timer, MPLS_TIMER_ONESHOT);
27027 + LDP_EXIT(g->user_data, "ldp_session_backoff-error");
27029 + goto ldp_session_backoff_end;
27031 + } else if (s->oper_role == LDP_PASSIVE) {
27032 + /* this is a passive session that never received an init, kill it
27033 + * session current on the global list and the timer holds a refcnt.
27034 + * shutdown takes this session off of the global list, so when the
27035 + * timer refcnt is released the session will be deleted */
27036 + ldp_session_shutdown(g, s, MPLS_BOOL_TRUE);
27037 + } else {
27038 + MPLS_ASSERT(0);
27041 + mpls_timer_stop(g->timer_handle, timer);
27042 + mpls_timer_delete(g->timer_handle, timer);
27043 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
27045 +ldp_session_backoff_end:
27047 + mpls_lock_release(g->global_lock);
27049 + LDP_EXIT(g->user_data, "ldp_session_backoff");
27052 +ldp_session *ldp_session_create()
27054 + ldp_session *s = (ldp_session *) mpls_malloc(sizeof(ldp_session));
27056 + if (s) {
27057 + memset(s, 0, sizeof(ldp_session));
27058 + MPLS_REFCNT_INIT(s, 0);
27059 + MPLS_LIST_ELEM_INIT(s, _global);
27060 + MPLS_LIST_INIT(&s->outlabel_root, ldp_outlabel);
27061 + MPLS_LIST_INIT(&s->attr_root, ldp_attr);
27062 + MPLS_LIST_INIT(&s->adj_root, ldp_adj);
27063 + mpls_link_list_init(&s->inlabel_root);
27064 + mpls_link_list_init(&s->addr_root);
27066 + s->on_global = MPLS_BOOL_FALSE;
27067 + s->tx_buffer = ldp_buf_create(MPLS_PDUMAXLEN);
27068 + s->tx_message = ldp_mesg_create();
27069 + s->index = _ldp_session_get_next_index();
27070 + s->oper_role = LDP_NONE;
27072 + return s;
27075 +mpls_return_enum ldp_session_attempt_setup(ldp_global *g, ldp_session *s) {
27076 + mpls_socket_handle socket = mpls_socket_create_tcp(g->socket_handle);
27077 + mpls_return_enum retval;
27079 + LDP_ENTER(g->user_data, "ldp_session_attempt_setup");
27081 + if (mpls_socket_handle_verify(g->socket_handle, socket) == MPLS_BOOL_FALSE) {
27082 + return MPLS_FAILURE;
27084 + if (mpls_socket_options(g->socket_handle, socket, MPLS_SOCKOP_NONBLOCK) ==
27085 + MPLS_FAILURE) {
27086 + goto ldp_session_attempt_setup_error;
27089 + retval = mpls_socket_tcp_connect(g->socket_handle, socket, &s->remote_dest);
27091 + switch (retval) {
27092 + case MPLS_NON_BLOCKING:
27094 + LDP_TRACE_OUT(g->user_data,
27095 + "ldp_session_attempt_setup: MPLS_NON_BLOCKING\n");
27096 + mpls_socket_writelist_add(g->socket_handle, socket, (void *)s,
27097 + MPLS_SOCKET_TCP_CONNECT);
27098 + break;
27100 + case MPLS_SUCCESS:
27102 + LDP_TRACE_OUT(g->user_data,
27103 + "ldp_session_attempt_setup: MPLS_SUCCESS\n");
27104 + if (ldp_state_machine(g, s, NULL, NULL, LDP_EVENT_CONNECT, NULL,
27105 + NULL) == MPLS_FAILURE) {
27106 + goto ldp_session_attempt_setup_error;
27108 + break;
27110 + default:
27112 + LDP_TRACE_OUT(g->user_data,
27113 + "ldp_session_attempt_setup: MPLS_FAILURE\n");
27114 + goto ldp_session_attempt_setup_error;
27116 + break;
27119 + s->socket = socket;
27120 + LDP_EXIT(g->user_data, "ldp_session_attempt_setup");
27121 + return MPLS_SUCCESS;
27123 +ldp_session_attempt_setup_error:
27125 + mpls_socket_close(g->socket_handle, socket);
27126 + LDP_EXIT(g->user_data, "ldp_session_attempt_setup");
27127 + return MPLS_FAILURE;
27130 +mpls_return_enum ldp_session_create_active(ldp_global * g, ldp_adj * a)
27132 + mpls_return_enum retval = MPLS_FAILURE;
27133 + mpls_inet_addr *addr = NULL;
27134 + ldp_session *s = NULL;
27135 + ldp_adj* ap;
27137 + MPLS_ASSERT(g && a && (!a->session));
27139 + LDP_ENTER(g->user_data, "ldp_session_create_active");
27141 + ap = MPLS_LIST_HEAD(&g->adj);
27142 + while (ap) {
27143 + if ((!mpls_inet_addr_compare(&ap->remote_lsr_address,
27144 + &a->remote_lsr_address)) &&
27145 + ap->remote_label_space == a->remote_label_space &&
27146 + a->index != ap->index && ap->session) {
27147 + ldp_adj_add_session(a, ap->session);
27148 + retval = MPLS_SUCCESS;
27149 + goto ldp_session_create_active;
27151 + ap = MPLS_LIST_NEXT(&g->adj, ap, _global);
27154 + if ((s = ldp_session_create())) {
27155 + if (a->remote_transport_address.type != MPLS_FAMILY_NONE) {
27156 + addr = &a->remote_transport_address;
27157 + } else {
27158 + addr = &a->remote_source_address;
27161 + _ldp_global_add_session(g, s);
27162 + ldp_adj_add_session(a, s);
27163 + s->state = LDP_STATE_NON_EXIST;
27165 + memcpy(&s->remote_dest.addr, addr, sizeof(mpls_inet_addr));
27166 + s->remote_dest.port = s->cfg_peer_tcp_port;
27168 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
27169 + "ldp_session_create_active: (%d) changed to NON_EXIST\n", s->index);
27171 + if (ldp_session_attempt_setup(g, s) != MPLS_SUCCESS) {
27172 + /* go into backoff */
27173 + ldp_session_backoff_start(g, s);
27175 + retval = MPLS_SUCCESS;
27178 +ldp_session_create_active:
27180 + LDP_EXIT(g->user_data, "ldp_session_create_active");
27181 + return retval;
27184 +ldp_session *ldp_session_create_passive(ldp_global * g,
27185 + mpls_socket_handle socket, mpls_dest * from)
27187 + ldp_session *s = NULL;
27189 + MPLS_ASSERT(g);
27191 + LDP_ENTER(g->user_data, "ldp_session_create_passive");
27193 + if ((s = ldp_session_create())) {
27194 + s->socket = socket;
27195 + s->state = LDP_STATE_NON_EXIST;
27197 + if (mpls_socket_options(g->socket_handle, socket, MPLS_SOCKOP_NONBLOCK) ==
27198 + MPLS_SUCCESS) {
27199 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
27200 + "ldp_session_create_passive: (%d) changed to NON_EXIST\n", s->index);
27201 + _ldp_global_add_session(g, s);
27202 + } else {
27203 + ldp_session_delete(s);
27204 + s = NULL;
27208 + LDP_EXIT(g->user_data, "ldp_session_create_passive (%p)", s);
27210 + return s;
27213 +void ldp_session_delete(ldp_session * s)
27215 + LDP_PRINT(NULL, "session delete");
27216 + MPLS_REFCNT_ASSERT(s, 0);
27217 + ldp_buf_delete(s->tx_buffer);
27218 + ldp_mesg_delete(s->tx_message);
27219 + mpls_free(s);
27222 +mpls_return_enum ldp_session_startup(ldp_global * g, ldp_session * s)
27224 + mpls_return_enum retval = MPLS_FAILURE;
27225 + ldp_addr *addr;
27227 + void (*callback) (mpls_timer_handle timer, void *extra, mpls_cfg_handle g);
27229 + MPLS_ASSERT(s && g && (s->oper_role != LDP_NONE));
27231 + LDP_ENTER(g->user_data, "ldp_session_startup");
27233 + /* when we make it to operational, get rid of any backoff timers */
27234 + ldp_session_backoff_stop(g, s);
27235 + s->state = LDP_STATE_OPERATIONAL;
27236 + s->oper_up = time(NULL);
27238 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
27239 + "ldp_session_startup: (%d) changed to OPERATIONAL\n", s->index);
27241 + /*
27242 + * if configured to distribute addr messages walk the if table
27243 + * and send an addr message for each
27244 + */
27245 + if (g->send_address_messages) {
27246 + addr = MPLS_LIST_HEAD(&g->addr);
27247 + while (addr) {
27248 + /* only locally attached addrs will have a valid iff */
27249 + if (addr->iff) {
27250 + if (ldp_addr_send(g, s, &addr->address) != MPLS_SUCCESS)
27251 + goto ldp_session_startup_end;
27253 + addr = MPLS_LIST_NEXT(&g->addr, addr, _global);
27257 + /* depending on the mode, grab a pointer to the correct callback */
27258 + switch (s->oper_distribution_mode) {
27259 + case LDP_DISTRIBUTION_ONDEMAND:
27260 + callback = ldp_label_request_initial_callback;
27261 + break;
27262 + case LDP_DISTRIBUTION_UNSOLICITED:
27263 + callback = ldp_label_mapping_initial_callback;
27264 + break;
27265 + default:
27266 + MPLS_ASSERT(0);
27269 + /*
27270 + * create a timer which will go about "chunking" the initial
27271 + * set of requests or mappings
27272 + */
27273 + MPLS_REFCNT_HOLD(s);
27274 + s->initial_distribution_timer = mpls_timer_create(g->timer_handle,
27275 + MPLS_UNIT_SEC, LDP_REQUEST_CHUNK, (void *)s, g, callback);
27277 + if (mpls_timer_handle_verify(g->timer_handle,
27278 + s->initial_distribution_timer) == MPLS_BOOL_FALSE) {
27279 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
27281 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
27282 + "ldp_session_startup: initial distrib error(%d)\n", s->index);
27284 + /* timer error, we might as well shutdown the session, it's usless */
27285 + s->shutdown_notif = LDP_NOTIF_INTERNAL_ERROR;
27286 + s->shutdown_fatal = MPLS_BOOL_TRUE;
27287 + retval = MPLS_FAILURE;
27288 + } else {
27289 + mpls_timer_start(g->timer_handle, s->initial_distribution_timer,
27290 + MPLS_TIMER_ONESHOT);
27291 + retval = MPLS_SUCCESS;
27294 +ldp_session_startup_end:
27296 + LDP_EXIT(g->user_data, "ldp_session_startup");
27298 + return retval;
27301 +void ldp_session_shutdown(ldp_global * g, ldp_session * s, mpls_bool complete)
27303 + ldp_addr *a = NULL;
27304 + ldp_attr *attr = NULL;
27305 + ldp_attr *nattr = NULL;
27306 + ldp_adj* ap;
27308 + MPLS_ASSERT(s);
27310 + LDP_ENTER(g->user_data, "ldp_session_shutdown");
27312 + /*
27313 + * hold a refcount so this session doesn't disappear on us
27314 + * while cleaning up
27315 + */
27316 + MPLS_REFCNT_HOLD(s);
27318 + s->state = LDP_STATE_NONE;
27319 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
27320 + "ldp_session_shutdown: (%d) changed to NONE\n", s->index);
27322 + /*
27323 + * kill the timers for the session
27324 + */
27325 + if (mpls_timer_handle_verify(g->timer_handle, s->keepalive_recv_timer) ==
27326 + MPLS_BOOL_TRUE) {
27327 + mpls_timer_stop(g->timer_handle, s->keepalive_recv_timer);
27328 + mpls_timer_delete(g->timer_handle, s->keepalive_recv_timer);
27329 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
27330 + s->keepalive_recv_timer = (mpls_timer_handle) 0;
27332 + if (mpls_timer_handle_verify(g->timer_handle, s->keepalive_send_timer) ==
27333 + MPLS_BOOL_TRUE) {
27334 + mpls_timer_stop(g->timer_handle, s->keepalive_send_timer);
27335 + mpls_timer_delete(g->timer_handle, s->keepalive_send_timer);
27336 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
27337 + s->keepalive_send_timer = (mpls_timer_handle) 0;
27339 + if (mpls_timer_handle_verify(g->timer_handle,s->initial_distribution_timer) ==
27340 + MPLS_BOOL_TRUE) {
27341 + mpls_timer_stop(g->timer_handle, s->initial_distribution_timer);
27342 + mpls_timer_delete(g->timer_handle, s->initial_distribution_timer);
27343 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
27344 + s->initial_distribution_timer = (mpls_timer_handle) 0;
27347 + /*
27348 + * get rid of the socket
27349 + */
27350 + if (mpls_socket_handle_verify(g->socket_handle, s->socket) ==
27351 + MPLS_BOOL_TRUE) {
27352 + mpls_socket_readlist_del(g->socket_handle, s->socket);
27353 + mpls_socket_close(g->socket_handle, s->socket);
27356 + /*
27357 + * get rid of out cached keepalive
27358 + */
27359 + if (s->keepalive != NULL) {
27360 + ldp_mesg_delete(s->keepalive);
27361 + s->keepalive = NULL;
27364 + ldp_session_backoff_stop(g,s);
27366 + attr = MPLS_LIST_HEAD(&g->attr);
27367 + while (attr != NULL) {
27368 + nattr = MPLS_LIST_NEXT(&g->attr, attr, _global);
27369 + if (attr->session && attr->session->index == s->index) {
27370 + /*
27371 + * ldp_attr_remove_complete removed everythig associated with the attr.
27372 + * in and out labels, and cross connects as well
27373 + */
27374 + ldp_attr_remove_complete(g, attr, complete);
27376 + attr = nattr;
27379 + /*
27380 + * clean up the addrs we created
27381 + */
27382 + while ((a = (ldp_addr*)mpls_link_list_head_data(&s->addr_root))) {
27383 + ldp_session_del_addr(g, s, a);
27386 + /*
27387 + * if we have an adj AND we are shuting down for a protocol reason, start a
27388 + * backoff timer, so we can try again in the near future
27389 + */
27390 + if ((complete == MPLS_BOOL_TRUE) || (s->oper_role != LDP_ACTIVE)) {
27391 + while ((ap = MPLS_LIST_HEAD(&s->adj_root))) {
27392 + ldp_adj_del_session(ap, s);
27395 + if (s->on_global == MPLS_BOOL_TRUE) {
27396 + _ldp_global_del_session(g, s);
27398 + } else {
27399 + if (s->oper_role == LDP_ACTIVE) {
27400 + ldp_session_backoff_start(g, s);
27404 + /*
27405 + * it is safe to release this refcnt now, if it is the last one, the
27406 + * session will be deleted (this will be the last one in the case of
27407 + * 'complete' == MPLS_BOOL_TRUE
27408 + */
27409 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
27411 + LDP_EXIT(g->user_data, "ldp_session_shutdown");
27414 +mpls_return_enum ldp_session_maintain_timer(ldp_global * g, ldp_session * s,
27415 + int flag)
27417 + mpls_return_enum result = MPLS_FAILURE;
27419 + LDP_ENTER(g->user_data, "ldp_session_maintain_timer");
27421 + /*
27422 + * all session keepalive maintainance comes through here (SEND and RECV)
27423 + */
27424 + if (flag == LDP_KEEPALIVE_RECV) {
27425 + mpls_timer_stop(g->timer_handle, s->keepalive_recv_timer);
27426 + result = mpls_timer_start(g->timer_handle, s->keepalive_recv_timer,
27427 + MPLS_TIMER_ONESHOT);
27428 + } else {
27429 + mpls_timer_stop(g->timer_handle, s->keepalive_send_timer);
27430 + result = mpls_timer_start(g->timer_handle, s->keepalive_send_timer,
27431 + MPLS_TIMER_REOCCURRING);
27434 + LDP_EXIT(g->user_data, "ldp_session_maintain_timer");
27436 + return result;
27439 +void ldp_session_add_outlabel(ldp_session * s, ldp_outlabel * o)
27441 + MPLS_ASSERT(s && o);
27442 + MPLS_REFCNT_HOLD(o);
27443 + MPLS_LIST_ADD_HEAD(&s->outlabel_root, o, _session, ldp_outlabel);
27444 + _ldp_outlabel_add_session(o, s);
27447 +void ldp_session_del_outlabel(ldp_global * g,ldp_session * s, ldp_outlabel * o)
27449 + MPLS_ASSERT(s && o);
27450 + MPLS_LIST_REMOVE(&s->outlabel_root, o, _session);
27451 + _ldp_outlabel_del_session(o);
27452 + MPLS_REFCNT_RELEASE2(g, o, ldp_outlabel_delete);
27455 +mpls_return_enum ldp_session_add_inlabel(ldp_global * g,ldp_session * s, ldp_inlabel * i)
27457 + MPLS_ASSERT(s && i);
27458 + MPLS_REFCNT_HOLD(i);
27459 + if (mpls_link_list_add_tail(&s->inlabel_root, i) == MPLS_SUCCESS) {
27460 + if (_ldp_inlabel_add_session(i, s) == MPLS_SUCCESS) {
27461 + return MPLS_SUCCESS;
27463 + mpls_link_list_remove_data(&s->inlabel_root, i);
27465 + MPLS_REFCNT_RELEASE2(g, i, ldp_inlabel_delete);
27466 + return MPLS_FAILURE;
27469 +void ldp_session_del_inlabel(ldp_global * g,ldp_session * s, ldp_inlabel * i)
27471 + MPLS_ASSERT(s && i);
27472 + mpls_link_list_remove_data(&s->inlabel_root, i);
27473 + _ldp_inlabel_del_session(i, s);
27474 + MPLS_REFCNT_RELEASE2(g, i, ldp_inlabel_delete)
27477 +void _ldp_session_add_attr(ldp_session * s, ldp_attr * a)
27479 + MPLS_ASSERT(s && a);
27480 + MPLS_REFCNT_HOLD(a);
27481 + MPLS_LIST_ADD_HEAD(&s->attr_root, a, _session, ldp_attr);
27484 +void _ldp_session_del_attr(ldp_global *g, ldp_session * s, ldp_attr * a)
27486 + MPLS_ASSERT(s && a);
27487 + MPLS_LIST_REMOVE(&s->attr_root, a, _session);
27488 + MPLS_REFCNT_RELEASE2(g, a, ldp_attr_delete);
27491 +mpls_return_enum ldp_session_add_addr(ldp_global *g, ldp_session * s,
27492 + ldp_addr * a)
27494 + struct mpls_link_list_node *lln;
27495 + struct mpls_link_list_node *llnp;
27496 + ldp_addr *data;
27498 + MPLS_ASSERT(s && a);
27500 + MPLS_REFCNT_HOLD(a);
27501 + lln = mpls_link_list_node_create(a);
27502 + if (lln) {
27503 + if (_ldp_addr_add_session(a, s) == MPLS_SUCCESS) {
27504 + MPLS_LINK_LIST_LOOP(&s->addr_root, data, llnp) {
27505 + if (data->index > a->index) {
27506 + mpls_link_list_add_node_before(&s->addr_root, llnp, lln);
27507 + return MPLS_SUCCESS;
27511 + mpls_link_list_add_node_tail(&s->addr_root, lln);
27512 + return MPLS_SUCCESS;
27514 + mpls_link_list_node_delete(lln);
27516 + MPLS_REFCNT_RELEASE2(g, a, ldp_addr_delete);
27517 + return MPLS_FAILURE;
27520 +void ldp_session_del_addr(ldp_global *g, ldp_session * s, ldp_addr * a) {
27521 + MPLS_ASSERT(s && a);
27522 + mpls_link_list_remove_data(&s->addr_root, a);
27523 + _ldp_addr_del_session(a, s);
27524 + MPLS_REFCNT_RELEASE2(g, a, ldp_addr_delete);
27527 +void _ldp_session_add_adj(ldp_session * s, ldp_adj * a)
27529 + ldp_adj *ap = NULL;
27530 + struct in_addr lsr_address;
27532 + MPLS_ASSERT(s && a);
27533 + MPLS_REFCNT_HOLD(a);
27535 + s->cfg_remote_in_ttl_less_domain = a->entity->remote_in_ttl_less_domain;
27536 + s->cfg_distribution_mode = a->entity->label_distribution_mode;
27537 + s->cfg_loop_detection_mode = a->entity->loop_detection_mode;
27538 + s->cfg_label_request_count = a->entity->label_request_count;
27539 + s->cfg_label_request_timer = a->entity->label_request_timer;
27540 + s->cfg_label_space = ldp_entity_label_space(a->entity);
27541 + s->cfg_path_vector_limit = a->entity->path_vector_limit;
27542 + s->cfg_hop_count_limit = a->entity->hop_count_limit;
27543 + s->cfg_peer_tcp_port = a->entity->remote_tcp_port;
27544 + s->cfg_keepalive = a->entity->keepalive_timer;
27545 + s->cfg_max_pdu = a->entity->max_pdu;
27547 + lsr_address.s_addr = htonl(a->remote_lsr_address.u.ipv4);
27548 + sprintf(s->session_name, "%s:%d", inet_ntoa(lsr_address),
27549 + a->remote_label_space);
27550 + s->oper_role = a->role;
27552 + ap = MPLS_LIST_HEAD(&s->adj_root);
27553 + while (ap) {
27554 + if (ap->index > a->index) {
27555 + MPLS_LIST_INSERT_BEFORE(&s->adj_root, ap, a, _session);
27556 + return;
27558 + ap = MPLS_LIST_NEXT(&s->adj_root, ap, _session);
27560 + MPLS_LIST_ADD_TAIL(&s->adj_root, a, _session, ldp_adj);
27563 +void _ldp_session_del_adj(ldp_session * s, ldp_adj * a)
27565 + MPLS_ASSERT(s && a);
27566 + MPLS_LIST_REMOVE(&s->adj_root, a, _session);
27567 + MPLS_REFCNT_RELEASE(a, ldp_adj_delete);
27570 +uint32_t _ldp_session_get_next_index()
27572 + uint32_t retval = _ldp_session_next_index;
27574 + _ldp_session_next_index++;
27575 + if (retval > _ldp_session_next_index) {
27576 + _ldp_session_next_index = 1;
27578 + return retval;
27581 +mpls_return_enum ldp_session_find_raddr_index(ldp_session * s, uint32_t index,
27582 + ldp_addr ** addr)
27584 + struct mpls_link_list_node *lln;
27585 + ldp_addr *a = NULL;
27587 + if (s && index > 0) {
27588 + /* because we sort our inserts by index, this lets us know
27589 + if we've "walked" past the end of the list */
27591 + if (mpls_link_list_isempty(&s->addr_root)) {
27592 + *addr = NULL;
27593 + return MPLS_END_OF_LIST;
27596 + if ((a = (ldp_addr*)mpls_link_list_tail_data(&s->addr_root))) {
27597 + if (a->index < index) {
27598 + *addr = NULL;
27599 + return MPLS_END_OF_LIST;
27603 + MPLS_LINK_LIST_LOOP(&s->addr_root, a, lln) {
27604 + if (a->index == index) {
27605 + *addr = a;
27606 + return MPLS_SUCCESS;
27610 + *addr = NULL;
27611 + return MPLS_FAILURE;
27614 +mpls_return_enum ldp_session_backoff_stop(ldp_global * g, ldp_session * s)
27617 + LDP_ENTER(g->user_data, "ldp_session_backoff_stop");
27619 + s->backoff = 0;
27620 + if (mpls_timer_handle_verify(g->timer_handle, s->backoff_timer) ==
27621 + MPLS_BOOL_TRUE) {
27623 + mpls_timer_stop(g->timer_handle, s->backoff_timer);
27624 + mpls_timer_delete(g->timer_handle, s->backoff_timer);
27625 + s->backoff_timer = (mpls_timer_handle) 0;
27626 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
27629 + LDP_EXIT(g->user_data, "ldp_session_backoff_stop");
27631 + return MPLS_SUCCESS;
27634 +mpls_return_enum ldp_session_backoff_start(ldp_global * g, ldp_session * s)
27636 + mpls_bool valid;
27638 + MPLS_ASSERT(s);
27640 + LDP_ENTER(g->user_data, "ldp_session_backoff_start");
27642 + valid = mpls_timer_handle_verify(g->timer_handle,s->backoff_timer);
27644 + MPLS_ASSERT(valid == MPLS_BOOL_FALSE);
27646 + s->backoff += g->backoff_step;
27648 +#if 0 /* if the above assert shouldn't be made this code should be executed */
27650 + /* this should never happen, but if so */
27651 + mpls_timer_stop(g->timer_handle, s->backoff_timer);
27652 + mpls_timer_delete(g->timer_handle, s->backoff_timer);
27653 + s->backoff_timer = (mpls_timer_handle) 0;
27654 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
27657 + if (!s) { /* if we deleted session due to the above RELEASE */
27658 + LDP_EXIT(g->user_data, "ldp_session_backoff_start-error");
27659 + return MPLS_FAILURE;
27661 +#endif
27663 + MPLS_REFCNT_HOLD(s);
27664 + s->backoff_timer = mpls_timer_create(g->timer_handle, MPLS_UNIT_SEC,
27665 + s->backoff, (void *)s, g, ldp_session_backoff_callback);
27666 + if (mpls_timer_handle_verify(g->timer_handle, s->backoff_timer) ==
27667 + MPLS_BOOL_FALSE) {
27669 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
27670 + LDP_EXIT(g->user_data, "ldp_session_backoff_start-error");
27671 + return MPLS_FAILURE;
27674 + if (mpls_timer_start(g->timer_handle, s->backoff_timer,
27675 + MPLS_TIMER_ONESHOT) != MPLS_SUCCESS) {
27677 + mpls_timer_delete(g->timer_handle, s->backoff_timer);
27678 + MPLS_REFCNT_RELEASE(s, ldp_session_delete);
27679 + LDP_EXIT(g->user_data, "ldp_session_backoff_start-error");
27680 + return MPLS_FAILURE;
27683 + LDP_EXIT(g->user_data, "ldp_session_backoff_start");
27685 + return MPLS_SUCCESS;
27688 +ldp_session *ldp_session_for_nexthop(ldp_nexthop *nh)
27690 + MPLS_ASSERT(nh);
27692 + LDP_ENTER(g->user_data, "ldp_session_for_nexthop: 0x%04d", nh->info.type);
27694 + if (nh->info.type & MPLS_NH_IP) {
27695 + LDP_PRINT(g->user_data, "ldp_session_for_nexthop-addr: %p %p %p\n",
27696 + nh, nh->addr, nh->addr->session);
27697 + if (nh->addr->session) {
27698 + LDP_EXIT(g->user_data, "ldp_session_for_nexthop-addr: %p",
27699 + nh->addr->session);
27700 + return nh->addr->session;
27703 + if (nh->info.type & MPLS_NH_IF) {
27704 + ldp_session *s = NULL;
27705 + if (nh->iff && (s = mpls_link_list_head_data(&nh->iff->session_root))) {
27706 + LDP_EXIT(g->user_data, "ldp_session_for_nexthop-iff");
27707 + return s;
27710 + if (nh->info.type & MPLS_NH_OUTSEGMENT) {
27711 + MPLS_ASSERT(0);
27713 + LDP_EXIT(g->user_data, "ldp_session_for_nexthop-none");
27714 + return NULL;
27716 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_session.h quagga-mpls/ldpd/ldp_session.h
27717 --- quagga/ldpd/ldp_session.h 1969-12-31 18:00:00.000000000 -0600
27718 +++ quagga-mpls/ldpd/ldp_session.h 2006-10-16 22:36:28.000000000 -0500
27719 @@ -0,0 +1,52 @@
27722 + * Copyright (C) James R. Leu 2000
27723 + * jleu@mindspring.com
27725 + * This software is covered under the LGPL, for more
27726 + * info check out http://www.gnu.org/copyleft/lgpl.html
27727 + */
27729 +#ifndef _LDP_SESSION_H_
27730 +#define _LDP_SESSION_H_
27732 +#include "ldp_struct.h"
27734 +extern mpls_return_enum ldp_session_backoff_start(ldp_global * g,
27735 + ldp_session * s);
27736 +extern mpls_return_enum ldp_session_backoff_stop(ldp_global * g,
27737 + ldp_session * s);
27738 +extern mpls_return_enum ldp_session_create_active(ldp_global * g, ldp_adj * a);
27739 +extern ldp_session *ldp_session_create_passive(ldp_global * g,
27740 + mpls_socket_handle socket, mpls_dest * from);
27741 +extern ldp_session *ldp_session_create();
27742 +extern void ldp_session_delete(ldp_session * s);
27743 +extern mpls_return_enum ldp_session_startup(ldp_global * g, ldp_session * s);
27744 +extern void ldp_session_shutdown(ldp_global * g, ldp_session * s, mpls_bool);
27746 +extern void _ldp_session_add_attr(ldp_session * s, ldp_attr * a);
27747 +extern void _ldp_session_del_attr(ldp_global *g, ldp_session * s, ldp_attr * a);
27749 +extern void ldp_session_add_outlabel(ldp_session * s, ldp_outlabel * o);
27750 +extern void ldp_session_del_outlabel(ldp_global * g, ldp_session * s, ldp_outlabel * o);
27752 +extern mpls_return_enum ldp_session_add_inlabel(ldp_global * g, ldp_session * s,
27753 + ldp_inlabel * i);
27754 +extern void ldp_session_del_inlabel(ldp_global *g, ldp_session * s, ldp_inlabel * i);
27756 +extern mpls_return_enum ldp_session_add_addr(ldp_global *g, ldp_session * s, ldp_addr * a);
27757 +extern void ldp_session_del_addr(ldp_global *g, ldp_session * s, ldp_addr * a);
27759 +extern void _ldp_session_add_adj(ldp_session * s, ldp_adj * a);
27760 +extern void _ldp_session_del_adj(ldp_session * s, ldp_adj * a);
27762 +extern uint32_t _ldp_session_get_next_index();
27763 +extern mpls_return_enum ldp_session_maintain_timer(ldp_global * g,
27764 + ldp_session * s, int flag);
27766 +extern mpls_return_enum ldp_session_find_raddr_index(ldp_session * s,
27767 + uint32_t index, ldp_addr ** addr);
27769 +extern ldp_session *ldp_session_for_nexthop(ldp_nexthop *nh);
27771 +#endif
27772 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_state_funcs.c quagga-mpls/ldpd/ldp_state_funcs.c
27773 --- quagga/ldpd/ldp_state_funcs.c 1969-12-31 18:00:00.000000000 -0600
27774 +++ quagga-mpls/ldpd/ldp_state_funcs.c 2006-11-08 22:04:12.000000000 -0600
27775 @@ -0,0 +1,514 @@
27778 + * Copyright (C) James R. Leu 2000
27779 + * jleu@mindspring.com
27781 + * This software is covered under the LGPL, for more
27782 + * info check out http://www.gnu.org/copyleft/lgpl.html
27783 + */
27785 +#include <sys/socket.h>
27786 +#include "ldp_struct.h"
27787 +#include "ldp_global.h"
27788 +#include "ldp_session.h"
27789 +#include "ldp_entity.h"
27790 +#include "ldp_fec.h"
27791 +#include "ldp_adj.h"
27792 +#include "ldp_attr.h"
27793 +#include "ldp_mesg.h"
27794 +#include "ldp_hello.h"
27795 +#include "ldp_init.h"
27796 +#include "ldp_label_rel_with.h"
27797 +#include "ldp_label_mapping.h"
27798 +#include "ldp_label_request.h"
27799 +#include "ldp_addr.h"
27800 +#include "ldp_keepalive.h"
27801 +#include "ldp_label_request.h"
27802 +#include "ldp_label_mapping.h"
27803 +#include "ldp_notif.h"
27804 +#include "ldp_label_abort.h"
27805 +#include "ldp_inet_addr.h"
27807 +#include "mpls_assert.h"
27808 +#include "mpls_tree_impl.h"
27809 +#include "mpls_trace_impl.h"
27810 +#include "mpls_socket_impl.h"
27812 +mpls_return_enum ldp_state_new_adjacency(ldp_global * g, ldp_session * s,
27813 + ldp_adj * a, ldp_entity * e, uint32_t event, ldp_mesg * msg, mpls_dest * from)
27815 + mpls_inet_addr traddr, lsraddr, *addr;
27816 + ldp_adj *local_a = NULL;
27817 + int labelspace;
27818 + int hellotime;
27819 + int request = 0;
27820 + int target = 0;
27821 + uint32_t csn = 0;
27822 + mpls_return_enum retval = MPLS_FAILURE;
27824 + MPLS_ASSERT(msg && e);
27826 + LDP_ENTER(g->user_data, "ldp_state_new_adjacency");
27828 + ldp_mesg_hdr_get_labelspace(msg, &labelspace);
27829 + ldp_mesg_hdr_get_lsraddr(msg, &lsraddr);
27830 + ldp_mesg_hello_get_hellotime(msg, &hellotime);
27831 + ldp_mesg_hello_get_request(msg, &request);
27832 + ldp_mesg_hello_get_targeted(msg, &target);
27833 + ldp_mesg_hello_get_csn(msg, &csn);
27835 + if (ldp_mesg_hello_get_traddr(msg, &traddr) == MPLS_FAILURE) {
27836 + addr = NULL;
27837 + } else {
27838 + addr = &traddr;
27841 + e->mesg_rx++;
27843 + if ((local_a = ldp_adj_create(&from->addr, &lsraddr, labelspace,
27844 + hellotime, addr, csn)) == NULL) {
27845 + goto ldp_state_new_adjacency_end;
27847 + ldp_entity_add_adj(e, local_a);
27848 + _ldp_global_add_adj(g, local_a);
27849 + if (ldp_hello_process(g, local_a, e, hellotime, csn, addr, target,
27850 + request) != MPLS_SUCCESS) {
27851 + /* this can fail if we could not create an active session, or
27852 + * we're getting errored hellos,
27853 + * if this fails then undo the e<->a linking (which will delete a) */
27854 + ldp_entity_del_adj(e, local_a);
27855 + _ldp_global_del_adj(g, local_a);
27856 + } else if (ldp_adj_startup(g, local_a, request) != MPLS_SUCCESS) {
27857 + /* the only way this fail is if a timer could not be created
27858 + * if this fails then undo the e<->a linking (which will delete a) */
27859 + ldp_entity_del_adj(e, local_a);
27860 + _ldp_global_del_adj(g, local_a);
27861 + } else {
27862 + /* by this time, we will have a e<->a binding, and some timers,
27863 + * if we're active, there will also be an active session */
27864 + retval = MPLS_SUCCESS;
27867 +ldp_state_new_adjacency_end:
27869 + LDP_EXIT(g->user_data, "ldp_state_new_adjacency");
27870 + return retval;
27873 +mpls_return_enum ldp_state_maintainance(ldp_global * g, ldp_session * s,
27874 + ldp_adj * a, ldp_entity * e, uint32_t event, ldp_mesg * msg, mpls_dest * from)
27876 + mpls_inet_addr traddr, *addr;
27877 + int hellotime;
27878 + int request = 0;
27879 + int target = 0;
27880 + uint32_t csn = 0;
27881 + mpls_return_enum retval = MPLS_SUCCESS;
27883 + MPLS_ASSERT(msg && e);
27885 + LDP_ENTER(g->user_data, "ldp_state_maintainance");
27887 + if (ldp_mesg_hello_get_hellotime(msg, &hellotime) != MPLS_SUCCESS) {
27888 + retval = MPLS_FAILURE;
27889 + goto ldp_state_maintainance_end;
27892 + ldp_mesg_hello_get_request(msg, &request);
27893 + ldp_mesg_hello_get_targeted(msg, &target);
27894 + /* if there isn't a csn in the msg, then csn stays 0 */
27895 + ldp_mesg_hello_get_csn(msg, &csn);
27896 + if (ldp_mesg_hello_get_traddr(msg, &traddr) != MPLS_SUCCESS) {
27897 + addr = NULL;
27898 + } else {
27899 + addr = &traddr;
27902 + if (ldp_hello_process(g, a, e, hellotime, csn, addr, target,
27903 + request) != MPLS_SUCCESS) {
27904 + retval = MPLS_FAILURE;
27905 + goto ldp_state_maintainance_end;
27907 + retval = ldp_adj_maintain_timer(g, a);
27908 + e->mesg_rx++;
27910 +ldp_state_maintainance_end:
27912 + LDP_EXIT(g->user_data, "ldp_state_maintainance");
27914 + return retval;
27917 +mpls_return_enum ldp_state_recv_init(ldp_global * g, ldp_session * s,
27918 + ldp_adj * a, ldp_entity * e, uint32_t event, ldp_mesg * msg, mpls_dest * from)
27920 + mpls_inet_addr lsraddr;
27921 + ldp_adj* ap;
27922 + int labelspace = 0;
27923 + mpls_bool match = MPLS_BOOL_FALSE;
27925 + MPLS_ASSERT(msg && s);
27927 + LDP_ENTER(g->user_data, "ldp_state_recv_init");
27929 + /* we haven't tied this session to an adj yet, at a minimum we can
27930 + * now stop the backoff timer we started while waiting for this
27931 + * init to arrive */
27932 + ldp_session_backoff_stop(g, s);
27934 + ldp_mesg_hdr_get_lsraddr(msg, &lsraddr);
27935 + ldp_mesg_hdr_get_labelspace(msg, &labelspace);
27937 + if (s->oper_role != LDP_ACTIVE) {
27938 + /* sessions being created from the ACTIVE side of an ADJ have already
27939 + * bound to the session */
27940 + /* there may be multiple ADJ that are matched! */
27941 + ap = MPLS_LIST_HEAD(&g->adj);
27942 + while (ap != NULL) {
27943 + if ((!mpls_inet_addr_compare(&lsraddr, &ap->remote_lsr_address)) &&
27944 + labelspace == ap->remote_label_space && !ap->session) {
27945 + ldp_adj_add_session(ap, s);
27946 + match = MPLS_BOOL_TRUE;
27948 + ap = MPLS_LIST_NEXT(&g->adj, ap, _global);
27951 + if (match == MPLS_BOOL_FALSE) {
27952 + LDP_PRINT(g->user_data, "ldp_state_recv_init: cannot find adj\n");
27953 + s->shutdown_notif = LDP_NOTIF_SESSION_REJECTED_NO_HELLO;
27954 + s->shutdown_fatal = MPLS_BOOL_FALSE;
27955 + goto ldp_state_recv_init_shutdown;
27959 + if (ldp_init_process(g, s, msg) == MPLS_FAILURE) {
27960 + LDP_PRINT(g->user_data, "ldp_state_recv_init: invalid INIT parameters\n");
27961 + /* session shutdown notif info set inside init_process */
27962 + goto ldp_state_recv_init_shutdown;
27965 + s->state = LDP_STATE_OPENREC;
27966 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
27967 + "ldp_state_recv_init: (%d) changed to OPENREC\n", s->index);
27969 + if (s->oper_role == LDP_PASSIVE) {
27970 + if (ldp_init_send(g, s) == MPLS_FAILURE) {
27971 + LDP_PRINT(g->user_data, "ldp_state_recv_init: unable to send INIT\n");
27972 + s->shutdown_notif = LDP_NOTIF_INTERNAL_ERROR;
27973 + s->shutdown_fatal = MPLS_BOOL_TRUE;
27974 + goto ldp_state_recv_init_shutdown;
27977 + ldp_keepalive_send(g, s);
27979 + LDP_EXIT(g->user_data, "ldp_state_recv_init");
27980 + return MPLS_SUCCESS;
27982 +ldp_state_recv_init_shutdown:
27984 + LDP_EXIT(g->user_data, "ldp_state_recv_init-error");
27985 + return MPLS_FAILURE;
27988 +mpls_return_enum ldp_state_connect(ldp_global * g, ldp_session * s, ldp_adj * a,
27989 + ldp_entity * e, uint32_t event, ldp_mesg * msg, mpls_dest * from)
27991 + mpls_return_enum retval = MPLS_SUCCESS;
27993 + LDP_ENTER(g->user_data, "ldp_state_connect");
27995 + mpls_socket_readlist_add(g->socket_handle, s->socket, (void *)s,
27996 + MPLS_SOCKET_TCP_DATA);
27997 + s->state = LDP_STATE_INITIALIZED;
27998 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
27999 + "ldp_state_connect: (%d) changed to INITIALIZED\n", s->index);
28001 + /* even though as part of creating an active session, the remote_dest
28002 + * was filled in, it had port 646 specified. 'from' now contains the
28003 + * real port info that our TCP session is connected to */
28004 + if (from) {
28005 + memcpy(&s->remote_dest, from, sizeof(mpls_dest));
28008 + if (s->oper_role == LDP_ACTIVE) {
28009 + if (ldp_init_send(g, s) == MPLS_SUCCESS) {
28010 + s->state = LDP_STATE_OPENSENT;
28011 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,
28012 + "ldp_state_connect: (%d) changed to OPENSENT\n", s->index);
28013 + } else {
28014 + s->shutdown_notif = LDP_NOTIF_INTERNAL_ERROR;
28015 + s->shutdown_fatal = MPLS_BOOL_TRUE;
28016 + retval = MPLS_FAILURE;
28018 + } else {
28019 + /* if this session is passive, we still are not associated with an
28020 + * adj. That will happen when we receive an init. There are no timers
28021 + * running yet, so we need to create a timer, to clean this socket
28022 + * up, if we do not receive a Init mesg, we'll overload the backoff
28023 + * timer for this purpose */
28024 + retval = ldp_session_backoff_start(g, s);
28027 + LDP_EXIT(g->user_data, "ldp_state_connect");
28029 + return retval;
28032 +mpls_return_enum ldp_state_finish_init(ldp_global * g, ldp_session * s,
28033 + ldp_adj * a, ldp_entity * e, uint32_t event, ldp_mesg * msg, mpls_dest * from)
28035 + mpls_return_enum retval;
28036 + MPLS_ASSERT(s);
28038 + LDP_ENTER(g->user_data, "ldp_state_finish_init");
28040 + retval = ldp_session_startup(g, s);
28042 + LDP_EXIT(g->user_data, "ldp_state_finish_init");
28044 + return MPLS_SUCCESS;
28047 +mpls_return_enum ldp_state_process(ldp_global * g, ldp_session * s, ldp_adj * a,
28048 + ldp_entity * e, uint32_t event, ldp_mesg * msg, mpls_dest * from)
28050 + mpls_return_enum retval = MPLS_SUCCESS;
28051 + ldp_attr *r_attr;
28052 + mpls_fec fec;
28053 + int i;
28055 + MPLS_ASSERT(s && msg);
28057 + LDP_ENTER(g->user_data, "ldp_state_process");
28059 + switch (msg->u.generic.flags.flags.msgType) {
28060 + case MPLS_LBLWITH_MSGTYPE:
28062 + mplsLdpLbl_W_R_Msg_t *rw = &msg->u.release;
28063 + ldp_fec *f;
28065 + for (i = 0; i < rw->fecTlv.numberFecElements; i++) {
28066 + fec_tlv2mpls_fec(&rw->fecTlv, i, &fec);
28067 + if (!(r_attr = ldp_attr_create(g, &fec))) {
28068 + goto ldp_state_process_error;
28071 + MPLS_REFCNT_HOLD(r_attr);
28073 + rel_with2attr(rw, r_attr);
28074 + f = ldp_fec_find2(g, &fec);
28075 + MPLS_REFCNT_HOLD(f);
28077 + retval = ldp_label_withdraw_process(g, s, a, e, r_attr, f);
28079 + MPLS_REFCNT_RELEASE2(g, f, ldp_fec_delete);
28080 + MPLS_REFCNT_RELEASE2(g, r_attr, ldp_attr_delete);
28081 + if (retval != MPLS_SUCCESS)
28082 + break;
28084 + break;
28086 + case MPLS_LBLREL_MSGTYPE:
28088 + mplsLdpLbl_W_R_Msg_t *rw = &msg->u.release;
28089 + ldp_fec *f;
28091 + for (i = 0; i < rw->fecTlv.numberFecElements; i++) {
28092 + fec_tlv2mpls_fec(&rw->fecTlv, i, &fec);
28093 + if (!(r_attr = ldp_attr_create(g, &fec))) {
28094 + goto ldp_state_process_error;
28097 + MPLS_REFCNT_HOLD(r_attr);
28099 + rel_with2attr(rw, r_attr);
28100 + f = ldp_fec_find2(g, &fec);
28101 + MPLS_REFCNT_HOLD(f);
28103 + retval = ldp_label_release_process(g, s, a, e, r_attr, f);
28105 + MPLS_REFCNT_RELEASE2(g, f, ldp_fec_delete);
28106 + MPLS_REFCNT_RELEASE2(g, r_attr, ldp_attr_delete);
28107 + if (retval != MPLS_SUCCESS)
28108 + break;
28110 + break;
28112 + case MPLS_LBLREQ_MSGTYPE:
28114 + mplsLdpLblReqMsg_t *req = &msg->u.request;
28115 + ldp_fec *f;
28117 + MPLS_ASSERT(req->fecTlv.numberFecElements == 1);
28119 + for (i = 0; i < req->fecTlv.numberFecElements; i++) {
28120 + fec_tlv2mpls_fec(&req->fecTlv, i, &fec);
28121 + if (!(r_attr = ldp_attr_create(g, &fec))) {
28122 + goto ldp_state_process_error;
28125 + MPLS_REFCNT_HOLD(r_attr);
28127 + req2attr(req, r_attr, LDP_ATTR_ALL & ~LDP_ATTR_FEC);
28128 + f = ldp_fec_find2(g, &fec);
28129 + MPLS_REFCNT_HOLD(f);
28131 + retval = ldp_label_request_process(g, s, a, e, r_attr, f);
28133 + MPLS_REFCNT_RELEASE2(g, f, ldp_fec_delete);
28134 + MPLS_REFCNT_RELEASE2(g, r_attr, ldp_attr_delete);
28135 + if (retval != MPLS_SUCCESS)
28136 + break;
28138 + break;
28140 + case MPLS_LBLMAP_MSGTYPE:
28142 + mplsLdpLblMapMsg_t *map = &msg->u.map;
28143 + ldp_fec *f;
28145 + for (i = 0; i < map->fecTlv.numberFecElements; i++) {
28146 + fec_tlv2mpls_fec(&map->fecTlv, i, &fec);
28147 + if (!(r_attr = ldp_attr_create(g, &fec))) {
28148 + goto ldp_state_process_error;
28151 + MPLS_REFCNT_HOLD(r_attr);
28153 + map2attr(map, r_attr, LDP_ATTR_ALL & ~LDP_ATTR_FEC);
28154 + f = ldp_fec_find2(g, &fec);
28155 + MPLS_REFCNT_HOLD(f);
28157 + retval = ldp_label_mapping_process(g, s, a, e, r_attr, f);
28159 + MPLS_REFCNT_RELEASE2(g, f, ldp_fec_delete);
28160 + MPLS_REFCNT_RELEASE2(g, r_attr, ldp_attr_delete);
28161 + if (retval != MPLS_SUCCESS)
28162 + break;
28164 + break;
28166 + case MPLS_LBLABORT_MSGTYPE:
28168 + mplsLdpLblAbortMsg_t *abrt = &msg->u.abort;
28169 + ldp_fec *f;
28171 + for (i = 0; i < abrt->fecTlv.numberFecElements; i++) {
28172 + fec_tlv2mpls_fec(&abrt->fecTlv, i, &fec);
28173 + if (!(r_attr = ldp_attr_create(g, &fec))) {
28174 + goto ldp_state_process_error;
28177 + MPLS_REFCNT_HOLD(r_attr);
28179 + abort2attr(abrt, r_attr, LDP_ATTR_ALL & ~LDP_ATTR_FEC);
28180 + f = ldp_fec_find2(g, &fec);
28181 + MPLS_REFCNT_HOLD(f);
28183 + retval = ldp_label_abort_process(g, s, a, e, r_attr, f);
28185 + MPLS_REFCNT_RELEASE2(g, f, ldp_fec_delete);
28186 + MPLS_REFCNT_RELEASE2(g, r_attr, ldp_attr_delete);
28187 + if (retval != MPLS_SUCCESS)
28188 + break;
28190 + break;
28192 + case MPLS_ADDRWITH_MSGTYPE:
28193 + case MPLS_ADDR_MSGTYPE:
28195 + retval = ldp_addr_process(g, s, e, msg);
28196 + break;
28198 + default:
28200 + MPLS_ASSERT(0);
28201 + break;
28205 + LDP_EXIT(g->user_data, "ldp_state_process");
28207 + return retval;
28209 +ldp_state_process_error:
28211 + LDP_EXIT(g->user_data, "ldp_state_process");
28213 + s->shutdown_notif = LDP_NOTIF_INTERNAL_ERROR;
28214 + s->shutdown_fatal = MPLS_BOOL_TRUE;
28215 + return MPLS_FAILURE;
28218 +mpls_return_enum ldp_state_ignore(ldp_global * g, ldp_session * session,
28219 + ldp_adj * adj, ldp_entity * entity, uint32_t event, ldp_mesg * msg,
28220 + mpls_dest * from)
28222 + return MPLS_SUCCESS;
28225 +mpls_return_enum ldp_state_close(ldp_global * g, ldp_session * s, ldp_adj * a,
28226 + ldp_entity * e, uint32_t event, ldp_mesg * msg, mpls_dest * from)
28229 + LDP_ENTER(g->user_data, "ldp_state_close: a = %p, e = %p s = %p",a,e,s);
28231 + /* JLEU: this need more work */
28232 + if (s) {
28233 + /* not sure why we got here but we should tear it completely down */
28234 + if (s->shutdown_fatal != MPLS_BOOL_TRUE) {
28235 + ldp_notif_send(g,s,NULL,s->shutdown_notif);
28237 + ldp_session_shutdown(g, s, MPLS_BOOL_TRUE);
28240 + LDP_EXIT(g->user_data, "ldp_state_close");
28241 + return MPLS_SUCCESS;
28244 +mpls_return_enum ldp_state_keepalive_maintainance(ldp_global * g,
28245 + ldp_session * s, ldp_adj * a, ldp_entity * e, uint32_t event, ldp_mesg * msg,
28246 + mpls_dest * from)
28248 + mpls_return_enum result;
28250 + MPLS_ASSERT(s);
28252 + LDP_ENTER(g->user_data, "ldp_state_keepalive_maintainance");
28253 + result = ldp_session_maintain_timer(g, s, LDP_KEEPALIVE_RECV);
28255 + LDP_EXIT(g->user_data, "ldp_state_keepalive_maintainance");
28257 + return result;
28260 +mpls_return_enum ldp_state_notif(ldp_global * g, ldp_session * s, ldp_adj * adj,
28261 + ldp_entity * entity, uint32_t event, ldp_mesg * msg, mpls_dest * from)
28264 + mpls_return_enum retval = MPLS_SUCCESS;
28265 + ldp_attr *r_attr = NULL;
28266 + mplsLdpNotifMsg_t *not = &msg->u.notif;
28268 + MPLS_ASSERT(s && msg);
28270 + LDP_ENTER(g->user_data, "ldp_state_notif");
28272 + if (!(r_attr = ldp_attr_create(g, NULL))) {
28273 + retval = MPLS_FAILURE;
28274 + goto ldp_state_notif_end;
28277 + MPLS_REFCNT_HOLD(r_attr);
28279 + not2attr(not, r_attr, LDP_ATTR_ALL);
28280 + retval = ldp_notif_process(g, s, adj, entity, r_attr);
28282 + MPLS_REFCNT_RELEASE2(g, r_attr, ldp_attr_delete);
28284 +ldp_state_notif_end:
28286 + LDP_EXIT(g->user_data, "ldp_state_notif");
28288 + return retval;
28290 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_state_machine.c quagga-mpls/ldpd/ldp_state_machine.c
28291 --- quagga/ldpd/ldp_state_machine.c 1969-12-31 18:00:00.000000000 -0600
28292 +++ quagga-mpls/ldpd/ldp_state_machine.c 2006-08-09 21:56:12.000000000 -0500
28293 @@ -0,0 +1,480 @@
28296 + * Copyright (C) James R. Leu 2000
28297 + * jleu@mindspring.com
28299 + * This software is covered under the LGPL, for more
28300 + * info check out http://www.gnu.org/copyleft/lgpl.html
28301 + */
28303 +#include "ldp_struct.h"
28304 +#include "ldp_global.h"
28305 +#include "ldp_session.h"
28306 +#include "ldp_entity.h"
28307 +#include "ldp_peer.h"
28308 +#include "ldp_if.h"
28309 +#include "ldp_adj.h"
28310 +#include "ldp_mesg.h"
28311 +#include "ldp_buf.h"
28312 +#include "ldp_state_machine.h"
28314 +#include "mpls_assert.h"
28315 +#include "mpls_socket_impl.h"
28316 +#include "mpls_lock_impl.h"
28317 +#include "mpls_trace_impl.h"
28319 +/* HELLO CONNECT INIT KEEP ADDR LABEL NOTIF CLOSE HTIMER KTIMER */
28320 +/* SES_NONE new ignore ignore ignore ignore ignore ignore close ignore ignore */
28321 +/* SES_NON_EXISTENT maint connect close close close close close close close ignore */
28322 +/* SES_INITIALIZED maint close recv_init close close close notif close close ignore */
28323 +/* SES_OPENSENT maint close recv_init close close close notif close close ignore */
28324 +/* SES_OPENREC maint close close finish close close notif close close close */
28325 +/* SES_OPERATIONAL maint close kmaint kmaint process process notif close close close */
28327 +int ldp_state_table[LDP_STATE_NUM][LDP_EVENT_NUM] = {
28328 + {0, 6, 6, 6, 6, 6, 6, 7, 6, 6},
28329 + {1, 3, 7, 7, 7, 7, 7, 7, 7, 6},
28330 + {1, 7, 2, 7, 7, 7, 9, 7, 7, 6},
28331 + {1, 7, 2, 7, 7, 7, 9, 7, 7, 6},
28332 + {1, 7, 7, 4, 7, 7, 9, 7, 7, 7},
28333 + {1, 7, 8, 8, 5, 5, 9, 7, 7, 7}};
28335 +mpls_return_enum ldp_buf_process(ldp_global * g, mpls_socket_handle socket,
28336 + ldp_buf * buf, void *extra, ldp_event_enum event, mpls_dest * from,
28337 + mpls_bool * more);
28339 +mpls_return_enum(*ldp_state_func[LDP_FUNC_NUM]) (ldp_global *, ldp_session *,
28340 + ldp_adj *, ldp_entity *, uint32_t, ldp_mesg *, mpls_dest *) = {
28341 + ldp_state_new_adjacency, /* 0 */
28342 + ldp_state_maintainance, /* 1 */
28343 + ldp_state_recv_init, /* 2 */
28344 + ldp_state_connect, /* 3 */
28345 + ldp_state_finish_init, /* 4 */
28346 + ldp_state_process, /* 5 */
28347 + ldp_state_ignore, /* 6 */
28348 + ldp_state_close, /* 7 */
28349 + ldp_state_keepalive_maintainance, /* 8 */
28350 + ldp_state_notif /* 9 */
28353 +#define LDP_FUNC_CLOSE 7
28355 +mpls_return_enum ldp_event(mpls_cfg_handle handle, mpls_socket_handle socket,
28356 + void *extra, ldp_event_enum event)
28358 + mpls_return_enum retval = MPLS_SUCCESS;
28359 + ldp_global *g = (ldp_global*)handle;
28361 + mpls_socket_handle socket_new = (mpls_socket_handle)0;
28362 + ldp_session *session = NULL;
28363 + ldp_entity *entity = NULL;
28364 + ldp_adj *adj = NULL;
28366 + uint8_t buffer[MPLS_PDUMAXLEN];
28367 + mpls_dest from;
28368 + ldp_mesg mesg;
28369 + ldp_buf buf;
28371 + LDP_ENTER(g->user_data, "ldp_event");
28373 + mpls_lock_get(g->global_lock);
28375 + switch (event) {
28376 + case LDP_EVENT_TCP_DATA:
28377 + case LDP_EVENT_UDP_DATA:
28379 + mpls_bool more;
28381 + buf.current = buffer;
28382 + buf.buffer = buffer;
28383 + buf.total = MPLS_PDUMAXLEN;
28384 + buf.size = 0;
28385 + buf.current_size = 0;
28386 + buf.want = 0;
28388 + /* do this so a failure will know which session caused it */
28389 + if (event == LDP_EVENT_TCP_DATA) {
28390 + session = extra;
28393 + do {
28394 + retval = ldp_buf_process(g, socket, &buf, extra, event, &from, &more);
28395 + } while (retval == MPLS_SUCCESS && more == MPLS_BOOL_TRUE);
28396 + break;
28398 + case LDP_EVENT_TCP_LISTEN:
28400 + socket_new = mpls_socket_tcp_accept(g->socket_handle, socket, &from);
28402 + if (mpls_socket_handle_verify(g->socket_handle, socket_new) ==
28403 + MPLS_BOOL_FALSE) {
28404 + LDP_PRINT(g->user_data, "Failed accepting socket\n");
28405 + retval = MPLS_FAILURE;
28406 + } else if (!(session = ldp_session_create_passive(g, socket_new,
28407 + &from))) {
28408 + mpls_socket_close(g->socket_handle, socket_new);
28409 + LDP_PRINT(g->user_data, "Failure creating passive session\n");
28410 + retval = MPLS_FATAL;
28411 + } else {
28412 + retval = ldp_state_machine(g, session, NULL, NULL,
28413 + LDP_EVENT_CONNECT, &mesg, &from);
28415 + break;
28417 + case LDP_EVENT_TCP_CONNECT:
28419 + retval = mpls_socket_connect_status(g->socket_handle, socket);
28420 + session = (ldp_session *)extra;
28422 + if (retval == MPLS_SUCCESS) {
28423 + /* only get this case if we did a non-block connect */
28424 + mpls_socket_writelist_del(g->socket_handle, socket);
28425 + retval = ldp_state_machine(g, session, NULL, NULL,
28426 + LDP_EVENT_CONNECT, &mesg, &from);
28427 + } else if (retval != MPLS_NON_BLOCKING) {
28428 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ERROR,
28429 + "ldp_event: LDP_EVENT_TCP_CONNECT errno = %d\n",
28430 + mpls_socket_get_errno(g->socket_handle, socket));
28431 + } else {
28432 + /* non-blocking connect is still blocking, we'll try again in a bit */
28433 + retval = MPLS_SUCCESS;
28435 + break;
28437 + case LDP_EVENT_CLOSE:
28439 + retval = ldp_state_machine(g, session, adj, entity,
28440 + LDP_EVENT_CLOSE, &mesg, &from);
28441 + break;
28443 + default:
28445 + MPLS_ASSERT(0);
28449 + /* ldp_state_machine return MPLS_SUCCESS when it has handled the event
28450 + to completion. If the handling off the event results in the session
28451 + needing to be shutdown MPLS_FAILURE is returned. If the handling of
28452 + the event requires the LDP be shutdown LD_FATAL is returned, and
28453 + passed back to the user. other values are invalid */
28455 + switch (retval) {
28456 + case MPLS_FAILURE:
28458 + /* if shutting down the session results in LDP_FATAL, then pass it
28459 + * back to the user */
28461 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ERROR,
28462 + "ldp_event: FAILURE executing a CLOSE\n");
28464 + retval = ldp_state_machine(g, session, adj, entity, LDP_EVENT_CLOSE,
28465 + NULL, &from);
28467 + if (retval == MPLS_FATAL) {
28468 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ERROR,
28469 + "ldp_event: CLOSE failed: FATAL propogated to the environemnt\n");
28471 + break;
28473 + case MPLS_FATAL:
28475 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ERROR,
28476 + "ldp_event: FATAL propogated to the environemnt\n");
28477 + break;
28479 + case MPLS_SUCCESS:
28481 + break;
28483 + default:
28485 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_ERROR,
28486 + "ldp_event: invalid return value of %d\n", retval);
28487 + break;
28491 + mpls_lock_release(g->global_lock);
28493 + LDP_EXIT(g->user_data, "ldp_event");
28495 + return retval;
28498 +mpls_return_enum ldp_state_machine(ldp_global * g, ldp_session * session,
28499 + ldp_adj * adj, ldp_entity * entity, uint32_t event, ldp_mesg * msg,
28500 + mpls_dest * from)
28502 + int state = LDP_STATE_NONE;
28503 + int func = 0;
28504 + mpls_return_enum retval = MPLS_FAILURE;
28506 + LDP_ENTER(g->user_data, "ldp_state_machine");
28508 + if (session) {
28509 + state = session->state;
28510 + } else if (adj) {
28511 + state = LDP_STATE_NON_EXIST;
28514 + if (state >= LDP_STATE_NONE && state <= LDP_STATE_OPERATIONAL) {
28515 + if (event <= LDP_EVENT_KTIMER) {
28516 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_STATE,
28517 + "FSM: state %d, event %d\n", state, event);
28518 + func = ldp_state_table[state][event];
28519 + retval = ldp_state_func[func] (g, session, adj, entity, event, msg, from);
28523 + LDP_EXIT(g->user_data, "ldp_state_machine");
28524 + return retval;
28527 +mpls_return_enum ldp_buf_process(ldp_global * g, mpls_socket_handle socket,
28528 + ldp_buf * buf, void *extra, ldp_event_enum event, mpls_dest * from,
28529 + mpls_bool * more)
28532 + mpls_return_enum retval = MPLS_SUCCESS;
28533 + ldp_session *session = NULL;
28534 + ldp_entity *entity = NULL;
28535 + ldp_adj *adj = NULL;
28536 + ldp_mesg mesg;
28538 + int size = 0;
28540 + LDP_ENTER(g->user_data, "ldp_buf_process");
28542 + *more = MPLS_BOOL_TRUE;
28544 + memset(&mesg, 0, sizeof(mesg));
28545 + if (!buf->want) {
28546 + buf->want = MPLS_LDP_HDRSIZE;
28549 +read_again:
28551 + switch (event) {
28552 + case LDP_EVENT_TCP_DATA:
28554 + session = (ldp_session *) extra;
28555 + MPLS_ASSERT(session);
28556 + session->mesg_rx++;
28558 + size = mpls_socket_tcp_read(g->socket_handle, socket,
28559 + buf->buffer + buf->size, buf->want - buf->size);
28561 + if (!size) {
28562 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
28563 + LDP_TRACE_FLAG_ERROR, "ldp_event: LDP_EVENT_TCP_DATA errno = %d\n",
28564 + mpls_socket_get_errno(g->socket_handle, socket));
28566 + retval = MPLS_FAILURE;
28567 + session->shutdown_notif = LDP_NOTIF_SHUTDOWN;
28568 + session->shutdown_fatal = MPLS_BOOL_TRUE;
28569 + goto ldp_event_end;
28570 + }
28572 + if (size < 0) {
28573 + retval = MPLS_SUCCESS;
28574 + *more = MPLS_BOOL_FALSE;
28575 + goto ldp_event_end;
28577 + break;
28579 + case LDP_EVENT_UDP_DATA:
28581 + size = mpls_socket_udp_recvfrom(g->socket_handle, socket,
28582 + buf->buffer + buf->size, buf->total - buf->size, from);
28584 + if (!size) {
28585 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
28586 + LDP_TRACE_FLAG_ERROR, "ldp_event: LDP_EVENT_UDP_DATA errno = %d\n",
28587 + mpls_socket_get_errno(g->socket_handle, socket));
28588 + retval = MPLS_FAILURE;
28589 + goto ldp_event_end;
28592 + if (size < 0) {
28593 + retval = MPLS_SUCCESS;
28594 + *more = MPLS_BOOL_FALSE;
28595 + goto ldp_event_end;
28597 + break;
28599 + default:
28601 + MPLS_ASSERT(0);
28602 + break;
28606 + buf->current_size += size;
28607 + buf->size += size;
28609 +decode_again:
28611 + if (buf->size < buf->want) {
28612 + retval = MPLS_SUCCESS;
28613 + *more = MPLS_BOOL_FALSE;
28614 + goto ldp_event_end;
28617 + /* upon succesful decode the pduLength will be non 0 */
28618 + if (!mesg.header.pduLength) {
28619 + if (ldp_decode_header(g, buf, &mesg) != MPLS_SUCCESS) {
28620 + retval = MPLS_FAILURE;
28622 + if (session) {
28623 + session->shutdown_notif = LDP_NOTIF_BAD_MESG_LEN;
28625 + goto ldp_event_end;
28628 + /* -buf->size is already 10 (the size of the full header
28629 + * -pduLength include 6 bytes of the header
28631 + * therefore add 4 so we can compare buf->want to buf->size and
28632 + * not have to adjust
28633 + */
28634 + buf->want = mesg.header.pduLength + 4;
28635 + if (buf->size < buf->want) {
28636 + goto read_again;
28638 + if (buf->size > buf->want) {
28639 + buf->current_size = buf->want - MPLS_LDP_HDRSIZE;
28643 + do {
28644 + if (ldp_decode_one_mesg(g, buf, &mesg) != MPLS_SUCCESS) {
28645 + retval = MPLS_FAILURE;
28647 + if (session) {
28648 + session->shutdown_notif = LDP_NOTIF_BAD_MESG_LEN;
28650 + goto ldp_event_end_loop;
28653 + switch (ldp_mesg_get_type(&mesg)) {
28654 + case MPLS_HELLO_MSGTYPE:
28656 + mpls_oper_state_enum oper_state = MPLS_OPER_DOWN;
28657 + mpls_inet_addr addr;
28658 + int labelspace = 0;
28659 + int targeted;
28661 + event = LDP_EVENT_HELLO;
28663 + targeted = 0;
28664 + ldp_mesg_hello_get_targeted(&mesg, &targeted);
28665 + ldp_mesg_hdr_get_lsraddr(&mesg, &addr);
28666 + ldp_mesg_hdr_get_labelspace(&mesg, &labelspace);
28668 + if (targeted) {
28669 + ldp_peer *peer = NULL;
28670 + if ((peer = ldp_global_find_peer_addr(g, &addr))) {
28671 + entity = ldp_peer_get_entity(peer);
28672 + oper_state = peer->oper_state;
28674 + } else {
28675 + ldp_if *iff = NULL;
28676 + if ((iff = ldp_global_find_if_handle(g, from->if_handle))) {
28677 + entity = ldp_if_get_entity(iff);
28678 + oper_state = iff->oper_state;
28682 + if (!entity) {
28683 + /* No entity! No choice but to ignore this packet */
28684 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
28685 + LDP_TRACE_FLAG_NORMAL, "ldp_event: unknown entity\n");
28686 + goto ldp_event_end_loop;
28687 + } else if (entity->admin_state == MPLS_ADMIN_DISABLE) {
28688 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
28689 + LDP_TRACE_FLAG_NORMAL, "ldp_event: entity is disabled\n");
28690 + goto ldp_event_end_loop;
28691 + } else if (oper_state == MPLS_OPER_DOWN) {
28692 + LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL,
28693 + LDP_TRACE_FLAG_NORMAL, "ldp_event: entity is down\n");
28694 + goto ldp_event_end_loop;
28698 + if ((adj = ldp_entity_find_adj(entity, &mesg))) {
28699 + session = adj->session;
28700 + } else {
28701 + session = NULL;
28703 + /* if we don't have an adj one will be create by state machine */
28704 + break;
28706 + case MPLS_INIT_MSGTYPE:
28708 + event = LDP_EVENT_INIT;
28709 + break;
28711 + case MPLS_NOT_MSGTYPE:
28713 + event = LDP_EVENT_NOTIF;
28714 + break;
28716 + case MPLS_KEEPAL_MSGTYPE:
28718 + event = LDP_EVENT_KEEP;
28719 + break;
28721 + case MPLS_LBLWITH_MSGTYPE:
28722 + case MPLS_LBLREL_MSGTYPE:
28723 + case MPLS_LBLREQ_MSGTYPE:
28724 + case MPLS_LBLMAP_MSGTYPE:
28725 + case MPLS_LBLABORT_MSGTYPE:
28727 + event = LDP_EVENT_LABEL;
28728 + break;
28730 + case MPLS_ADDR_MSGTYPE:
28731 + case MPLS_ADDRWITH_MSGTYPE:
28733 + event = LDP_EVENT_ADDR;
28734 + break;
28736 + default:
28738 + MPLS_ASSERT(0);
28742 + retval =
28743 + ldp_state_machine(g, session, adj, entity, event, &mesg, from);
28745 +ldp_event_end_loop:
28747 + if (retval != MPLS_SUCCESS) {
28748 + break;
28750 + } while ((buf->current_size > 0) && (*more == MPLS_BOOL_TRUE));
28752 + if (buf->want < buf->size) {
28753 + buf->current_size = buf->size - buf->want;
28754 + buf->size = buf->current_size;
28755 + memmove(buf->buffer, buf->current, buf->current_size);
28756 + } else {
28757 + buf->size = 0;
28760 + buf->current = buf->buffer;
28761 + memset(&mesg, 0, sizeof(mesg));
28762 + buf->want = MPLS_LDP_HDRSIZE;
28764 + if (buf->current_size) {
28765 + goto decode_again;
28768 +ldp_event_end:
28770 + LDP_EXIT(g->user_data, "ldp_buf_process");
28772 + return retval;
28774 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_state_machine.h quagga-mpls/ldpd/ldp_state_machine.h
28775 --- quagga/ldpd/ldp_state_machine.h 1969-12-31 18:00:00.000000000 -0600
28776 +++ quagga-mpls/ldpd/ldp_state_machine.h 2006-08-09 21:56:15.000000000 -0500
28777 @@ -0,0 +1,42 @@
28780 + * Copyright (C) James R. Leu 2000
28781 + * jleu@mindspring.com
28783 + * This software is covered under the LGPL, for more
28784 + * info check out http://www.gnu.org/copyleft/lgpl.html
28785 + */
28787 +#ifndef _LDP_STATE_MACHINE_H_
28788 +#define _LDP_STATE_MACHINE_H_
28790 +#include "ldp_struct.h"
28792 +extern mpls_return_enum ldp_event(mpls_cfg_handle g, mpls_socket_handle socket,
28793 + void *extra, ldp_event_enum event);
28795 +extern mpls_return_enum ldp_state_machine(ldp_global *, ldp_session *,
28796 + ldp_adj *, ldp_entity *, uint32_t, ldp_mesg *, mpls_dest *);
28798 +extern mpls_return_enum ldp_state_new_adjacency(ldp_global *, ldp_session *,
28799 + ldp_adj *, ldp_entity *, uint32_t, ldp_mesg *, mpls_dest *);
28800 +extern mpls_return_enum ldp_state_maintainance(ldp_global *, ldp_session *,
28801 + ldp_adj *, ldp_entity *, uint32_t, ldp_mesg *, mpls_dest *);
28802 +extern mpls_return_enum ldp_state_recv_init(ldp_global *, ldp_session *,
28803 + ldp_adj *, ldp_entity *, uint32_t, ldp_mesg *, mpls_dest *);
28804 +extern mpls_return_enum ldp_state_connect(ldp_global *, ldp_session *,
28805 + ldp_adj *, ldp_entity *, uint32_t, ldp_mesg *, mpls_dest *);
28806 +extern mpls_return_enum ldp_state_finish_init(ldp_global *, ldp_session *,
28807 + ldp_adj *, ldp_entity *, uint32_t, ldp_mesg *, mpls_dest *);
28808 +extern mpls_return_enum ldp_state_process(ldp_global *, ldp_session *,
28809 + ldp_adj *, ldp_entity *, uint32_t, ldp_mesg *, mpls_dest *);
28810 +extern mpls_return_enum ldp_state_ignore(ldp_global *, ldp_session *, ldp_adj *,
28811 + ldp_entity *, uint32_t, ldp_mesg *, mpls_dest *);
28812 +extern mpls_return_enum ldp_state_close(ldp_global *, ldp_session *, ldp_adj *,
28813 + ldp_entity *, uint32_t, ldp_mesg *, mpls_dest *);
28814 +extern mpls_return_enum ldp_state_keepalive_maintainance(ldp_global *,
28815 + ldp_session *, ldp_adj *, ldp_entity *, uint32_t, ldp_mesg *, mpls_dest *);
28816 +extern mpls_return_enum ldp_state_notif(ldp_global *, ldp_session *, ldp_adj *,
28817 + ldp_entity *, uint32_t, ldp_mesg *, mpls_dest *);
28819 +#endif
28820 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_struct.h quagga-mpls/ldpd/ldp_struct.h
28821 --- quagga/ldpd/ldp_struct.h 1969-12-31 18:00:00.000000000 -0600
28822 +++ quagga-mpls/ldpd/ldp_struct.h 2006-11-21 20:43:04.000000000 -0600
28823 @@ -0,0 +1,702 @@
28826 + * Copyright (C) James R. Leu 2000
28827 + * jleu@mindspring.com
28829 + * This software is covered under the LGPL, for more
28830 + * info check out http://www.gnu.org/copyleft/lgpl.html
28831 + */
28833 +#ifndef _LDP_STRUCT_H_
28834 +#define _LDP_STRUCT_H_
28836 +#include "mpls_struct.h"
28837 +#include "mpls_list.h"
28838 +#include "mpls_refcnt.h"
28840 +MPLS_LIST_ROOT(ldp_outlabel_list, ldp_outlabel);
28841 +MPLS_LIST_ROOT(ldp_resource_list, ldp_resource);
28842 +MPLS_LIST_ROOT(ldp_hop_list_list, ldp_hop_list);
28843 +MPLS_LIST_ROOT(ldp_inlabel_list, ldp_inlabel);
28844 +MPLS_LIST_ROOT(ldp_session_list, ldp_session);
28845 +MPLS_LIST_ROOT(ldp_nexthop_list, ldp_nexthop);
28846 +MPLS_LIST_ROOT(ldp_entity_list, ldp_entity);
28847 +MPLS_LIST_ROOT(ldp_tunnel_list, ldp_tunnel);
28848 +MPLS_LIST_ROOT(ldp_addr_list, ldp_addr);
28849 +MPLS_LIST_ROOT(ldp_attr_list, ldp_attr);
28850 +MPLS_LIST_ROOT(ldp_peer_list, ldp_peer);
28851 +MPLS_LIST_ROOT(_ldp_hop_list, ldp_hop);
28852 +MPLS_LIST_ROOT(ldp_adj_list, ldp_adj);
28853 +MPLS_LIST_ROOT(ldp_fec_list, ldp_fec);
28854 +MPLS_LIST_ROOT(ldp_fs_list, ldp_fs);
28855 +MPLS_LIST_ROOT(ldp_if_list, ldp_if);
28857 +typedef struct ldp_attr_list ldp_attr_list;
28859 +typedef enum {
28860 + LDP_UNKNOWN = 0,
28861 + LDP_DIRECT,
28862 + LDP_INDIRECT,
28863 +} ldp_entity_type_enum;
28865 +typedef enum {
28866 + LDP_CONTROL_INDEPENDENT = 1,
28867 + LDP_CONTROL_ORDERED
28868 +} ldp_control_mode;
28870 +typedef enum {
28871 + LDP_RETENTION_LIBERAL = 1,
28872 + LDP_RETENTION_CONSERVATIVE
28873 +} ldp_retention_mode;
28875 +typedef enum {
28876 + LDP_REPAIR_LOCAL = 1,
28877 + LDP_REPAIR_GLOBAL
28878 +} ldp_repaire_mode;
28880 +typedef enum {
28881 + LDP_LOOP_NONE = 0,
28882 + LDP_LOOP_HOPCOUNT,
28883 + LDP_LOOP_PATHVECTOR,
28884 + LDP_LOOP_HOPCOUNT_PATHVECTOR,
28885 + LDP_LOOP_OTHER,
28886 +} ldp_loop_detection_mode;
28888 +typedef enum {
28889 + LDP_DISTRIBUTION_UNSOLICITED = 0,
28890 + LDP_DISTRIBUTION_ONDEMAND = 1,
28891 +} ldp_distribution_mode;
28893 +typedef enum {
28894 + LDP_INFINIT = 0,
28895 +} ldp_count;
28897 +typedef enum {
28898 + LDP_NONE,
28899 + LDP_PASSIVE,
28900 + LDP_ACTIVE
28901 +} ldp_role_enum;
28903 +typedef enum {
28904 + LDP_EVENT_HELLO = 0,
28905 + LDP_EVENT_CONNECT,
28906 + LDP_EVENT_INIT,
28907 + LDP_EVENT_KEEP,
28908 + LDP_EVENT_ADDR,
28909 + LDP_EVENT_LABEL,
28910 + LDP_EVENT_NOTIF,
28911 + LDP_EVENT_CLOSE,
28912 + LDP_EVENT_HTIMER,
28913 + LDP_EVENT_KTIMER,
28914 + LDP_EVENT_TCP_LISTEN,
28915 + LDP_EVENT_TCP_CONNECT,
28916 + LDP_EVENT_UDP_DATA,
28917 + LDP_EVENT_TCP_DATA,
28918 +} ldp_event_enum;
28920 +typedef enum {
28921 + LDP_STATE_NONE = 0,
28922 + LDP_STATE_NON_EXIST,
28923 + LDP_STATE_INITIALIZED,
28924 + LDP_STATE_OPENSENT,
28925 + LDP_STATE_OPENREC,
28926 + LDP_STATE_OPERATIONAL
28927 +} ldp_state_enum;
28929 +typedef enum {
28930 + LDP_KEEPALIVE_RECV = 1,
28931 + LDP_KEEPALIVE_SEND
28932 +} ldp_keepalive_type;
28934 +typedef enum {
28935 + LDP_LSP_STATE_REQ_RECV,
28936 + LDP_LSP_STATE_REQ_SENT,
28937 + LDP_LSP_STATE_MAP_RECV,
28938 + LDP_LSP_STATE_MAP_SENT,
28939 + LDP_LSP_STATE_WITH_SENT,
28940 + LDP_LSP_STATE_WITH_RECV,
28941 + LDP_LSP_STATE_NO_LABEL_RESOURCE_SENT,
28942 + LDP_LSP_STATE_NO_LABEL_RESOURCE_RECV,
28943 + LDP_LSP_STATE_ABORT_SENT,
28944 + LDP_LSP_STATE_ABORT_RECV,
28945 + LDP_LSP_STATE_NOTIF_SENT,
28946 + LDP_LSP_STATE_NOTIF_RECV
28947 +} ldp_lsp_state;
28949 +typedef enum {
28950 + LDP_TRACE_FLAG_ADDRESS = 0x00000001,
28951 + LDP_TRACE_FLAG_BINDING = 0x00000002,
28952 + LDP_TRACE_FLAG_DEBUG = 0x00000004,
28953 + LDP_TRACE_FLAG_ERROR = 0x00000008,
28954 + LDP_TRACE_FLAG_EVENT = 0x00000010,
28955 + LDP_TRACE_FLAG_GENERAL = 0x00000020,
28956 + LDP_TRACE_FLAG_INIT = 0x00000040,
28957 + LDP_TRACE_FLAG_LABEL = 0x00000080,
28958 + LDP_TRACE_FLAG_NORMAL = 0x00000100,
28959 + LDP_TRACE_FLAG_NOTIF = 0x00000200,
28960 + LDP_TRACE_FLAG_PACKET_DUMP = 0x00000400,
28961 + LDP_TRACE_FLAG_PACKET = 0x00000800,
28962 + LDP_TRACE_FLAG_PATH = 0x00001000,
28963 + LDP_TRACE_FLAG_PERIODIC = 0x00002000,
28964 + LDP_TRACE_FLAG_POLICY = 0x00004000,
28965 + LDP_TRACE_FLAG_ROUTE = 0x00008000,
28966 + LDP_TRACE_FLAG_STATE = 0x00010000,
28967 + LDP_TRACE_FLAG_TASK = 0x00020000,
28968 + LDP_TRACE_FLAG_TIMER = 0x00040000,
28969 + LDP_TRACE_FLAG_ALL = 0xFFFFFFFF
28970 +} ldp_trace_flags;
28972 +typedef enum {
28973 + LDP_NOTIF_NONE = 0,
28974 + LDP_NOTIF_SUCCESS,
28975 + LDP_NOTIF_BAD_LDP_ID,
28976 + LDP_NOTIF_BAD_PROTO,
28977 + LDP_NOTIF_BAD_PDU_LEN,
28978 + LDP_NOTIF_UNKNOWN_MESG,
28979 + LDP_NOTIF_BAD_MESG_LEN,
28980 + LDP_NOTIF_UNKNOWN_TVL,
28981 + LDP_NOTIF_BAD_TLV_LEN,
28982 + LDP_NOTIF_MALFORMED_TLV,
28983 + LDP_NOTIF_HOLD_TIMER_EXPIRED,
28984 + LDP_NOTIF_SHUTDOWN,
28985 + LDP_NOTIF_LOOP_DETECTED,
28986 + LDP_NOTIF_UNKNOWN_FEC,
28987 + LDP_NOTIF_NO_ROUTE,
28988 + LDP_NOTIF_NO_LABEL_RESOURCES_AVAILABLE,
28989 + LDP_NOTIF_LABEL_RESOURCES_AVAILABLE,
28990 + LDP_NOTIF_SESSION_REJECTED_NO_HELLO,
28991 + LDP_NOTIF_SESSION_REJECTED_PARAMETERS_ADVERTISEMENT_MODE,
28992 + LDP_NOTIF_SESSION_REJECTED_PARAMETERS_MAX_PDU_LEN,
28993 + LDP_NOTIF_SESSION_REJECTED_PARAMETERS_LABEL_RANGE,
28994 + LDP_NOTIF_KEEPALIVE_TIMER_EXPIRED,
28995 + LDP_NOTIF_LABEL_ABORT,
28996 + LDP_NOTIF_MISSING_MSG_PARAMS,
28997 + LDP_NOTIF_UNSUPORTED_AF,
28998 + LDP_NOTIF_SESSION_REJECTED_BAD_KEEPALIVE_TIME,
28999 + LDP_NOTIF_INTERNAL_ERROR
29000 +} ldp_notif_status;
29002 +#define LDP_STATE_NUM 6
29003 +#define LDP_EVENT_NUM 10
29004 +#define LDP_FUNC_NUM 10
29006 +#include "ldp_defaults.h"
29007 +#include "mpls_handle_type.h"
29008 +#include "ldp_nortel.h"
29010 +typedef struct ldp_mesg {
29011 + mplsLdpHeader_t header;
29012 + union {
29013 + mplsLdpMsg_t generic;
29014 + mplsLdpInitMsg_t init;
29015 + mplsLdpNotifMsg_t notif;
29016 + mplsLdpHelloMsg_t hello;
29017 + mplsLdpKeepAlMsg_t keep;
29018 + mplsLdpAdrMsg_t addr;
29019 + mplsLdpLblMapMsg_t map;
29020 + mplsLdpLblReqMsg_t request;
29021 + mplsLdpLbl_W_R_Msg_t release;
29022 + mplsLdpLblAbortMsg_t abort;
29023 + } u;
29024 +} ldp_mesg;
29026 +typedef struct ldp_buf {
29027 + uint8_t *buffer;
29028 + uint8_t *current;
29029 + int current_size;
29030 + int size;
29031 + int total;
29032 + int want;
29033 +} ldp_buf;
29035 +typedef struct ldp_global {
29036 + struct ldp_outlabel_list outlabel;
29037 + struct ldp_resource_list resource;
29038 + struct ldp_hop_list_list hop_list;
29039 + struct ldp_inlabel_list inlabel;
29040 + struct ldp_nexthop_list nexthop;
29041 + struct ldp_session_list session;
29042 + struct ldp_tunnel_list tunnel;
29043 + struct ldp_entity_list entity;
29044 + struct ldp_peer_list peer;
29045 + struct ldp_attr_list attr;
29046 + struct ldp_addr_list addr;
29047 + struct ldp_adj_list adj;
29048 + struct ldp_if_list iff;
29049 + struct ldp_fec_list fec;
29051 + mpls_lock_handle global_lock;
29052 + mpls_instance_handle user_data;
29054 + mpls_tree_handle addr_tree;
29055 + mpls_tree_handle fec_tree;
29057 + mpls_socket_handle hello_socket;
29058 + mpls_socket_handle listen_socket;
29060 + mpls_timer_mgr_handle timer_handle;
29061 + mpls_socket_mgr_handle socket_handle;
29062 + mpls_fib_handle fib_handle;
29063 + mpls_ifmgr_handle ifmgr_handle;
29065 +#if MPLS_USE_LSR
29066 + mpls_cfg_handle lsr_handle;
29067 +#else
29068 + mpls_mpls_handle mpls_handle;
29069 +#endif
29071 + /*
29072 + * CSN changes with every MIB set, BUT only when a entity goes through
29073 + * shutdown/startup cycle will it grab the new CSN and use it in hellos
29074 + */
29075 + uint32_t configuration_sequence_number;
29077 + /*
29078 + * Message ID increaments with EVERY message, this means it will roll over
29079 + */
29080 + uint32_t message_identifier;
29082 + struct mpls_inet_addr lsr_identifier;
29083 + mpls_bool send_address_messages;
29084 + mpls_bool send_lsrid_mapping;
29085 + ldp_control_mode lsp_control_mode;
29086 + ldp_retention_mode label_retention_mode;
29087 + ldp_repaire_mode lsp_repair_mode;
29088 + mpls_bool propagate_release;
29089 + mpls_bool label_merge;
29090 + ldp_loop_detection_mode loop_detection_mode;
29091 + mpls_bool ttl_less_domain;
29092 + uint16_t local_tcp_port;
29093 + uint16_t local_udp_port;
29094 + uint16_t backoff_step;
29095 + int no_route_to_peer_time;
29097 + /*
29098 + * some global defaults, entities will inherit these values unless
29099 + * instructed otherwise
29100 + */
29101 + struct mpls_inet_addr transport_address;
29102 + uint16_t keepalive_timer;
29103 + uint16_t keepalive_interval;
29104 + uint16_t hellotime_timer;
29105 + uint16_t hellotime_interval;
29107 + mpls_admin_state_enum admin_state;
29108 +} ldp_global;
29110 +typedef struct ldp_entity {
29111 + MPLS_REFCNT_FIELD;
29112 + MPLS_LIST_ELEM(ldp_entity) _global;
29113 + struct ldp_adj_list adj_root;
29115 + ldp_entity_type_enum entity_type;
29116 + union {
29117 + struct ldp_peer *peer;
29118 + struct ldp_if *iff;
29119 + } p;
29121 + ldp_state_enum state;
29122 + uint32_t inherit_flag;
29123 + uint32_t sub_index;
29124 + uint32_t index;
29125 + struct mpls_inet_addr transport_address;
29126 + uint8_t protocol_version;
29127 + uint16_t remote_tcp_port;
29128 + uint16_t remote_udp_port;
29129 + uint16_t max_pdu;
29130 + uint16_t keepalive_timer;
29131 + uint16_t keepalive_interval;
29132 + uint16_t hellotime_timer;
29133 + uint16_t hellotime_interval;
29134 + uint16_t session_setup_count;
29135 + uint16_t session_backoff_timer;
29136 + ldp_distribution_mode label_distribution_mode;
29137 + uint8_t path_vector_limit;
29138 + uint8_t hop_count_limit;
29139 + uint8_t label_request_count;
29140 + uint16_t label_request_timer;
29141 + ldp_loop_detection_mode loop_detection_mode;
29142 + mpls_admin_state_enum admin_state;
29143 + mpls_bool remote_in_ttl_less_domain;
29144 + mpls_bool request_retry;
29146 + /* mesg counters */
29147 + uint32_t mesg_tx;
29148 + uint32_t mesg_rx;
29150 + /* only used for cfg gets */
29151 + int adj_index;
29152 + int adj_count;
29153 +} ldp_entity;
29155 +typedef struct ldp_if {
29156 + MPLS_REFCNT_FIELD;
29157 + MPLS_LIST_ELEM(ldp_if) _global;
29158 + struct mpls_link_list session_root;
29159 + struct ldp_nexthop_list nh_root;
29160 + struct ldp_addr_list addr_root;
29161 + struct ldp_entity *entity;
29162 + mpls_timer_handle hellotime_send_timer;
29163 + int hellotime_send_timer_duration;
29164 + int label_space;
29165 + uint32_t index;
29166 + mpls_if_handle handle;
29168 + struct ldp_mesg *tx_message;
29169 + struct ldp_buf *tx_buffer;
29170 + struct ldp_mesg *hello;
29172 + /* YES this is a dest, it is what we use for sendto */
29173 + struct mpls_dest dest;
29175 + mpls_oper_state_enum oper_state;
29176 + mpls_bool is_p2p;
29178 + /* only used for cfg gets */
29179 + uint32_t entity_index;
29180 +} ldp_if;
29182 +typedef struct ldp_peer {
29183 + MPLS_REFCNT_FIELD;
29184 + MPLS_LIST_ELEM(ldp_peer) _global;
29185 + struct ldp_entity *entity;
29186 + mpls_timer_handle no_route_to_peer_timer;
29187 + mpls_timer_handle hellotime_send_timer;
29188 + int hellotime_send_timer_duration;
29189 + int label_space;
29190 + uint32_t index;
29192 + struct ldp_mesg *tx_message;
29193 + struct ldp_buf *tx_buffer;
29194 + struct ldp_mesg *hello;
29196 + /* YES this is a dest, it is what we use for sendto */
29197 + struct mpls_dest dest;
29198 + ldp_role_enum target_role;
29200 + char peer_name[MPLS_MAX_IF_NAME];
29201 + mpls_oper_state_enum oper_state;
29203 + /* only used for cfg gets */
29204 + uint32_t entity_index;
29205 +} ldp_peer;
29207 +typedef struct ldp_session {
29208 + MPLS_REFCNT_FIELD;
29209 + MPLS_LIST_ELEM(ldp_session) _global;
29210 + struct ldp_outlabel_list outlabel_root;
29211 + struct mpls_link_list inlabel_root;
29212 + struct mpls_link_list addr_root;
29213 + struct ldp_attr_list attr_root;
29214 + struct ldp_adj_list adj_root;
29215 + mpls_timer_handle initial_distribution_timer;
29216 + mpls_timer_handle keepalive_recv_timer;
29217 + mpls_timer_handle keepalive_send_timer;
29218 + uint32_t index;
29219 + ldp_state_enum state;
29220 + uint32_t oper_up;
29221 + ldp_notif_status shutdown_notif;
29222 + mpls_bool shutdown_fatal;
29223 + mpls_socket_handle socket;
29224 + mpls_timer_handle backoff_timer;
29225 + int backoff;
29227 + /* operational values learned from initialization */
29228 + int oper_max_pdu;
29229 + int oper_keepalive;
29230 + int oper_keepalive_interval;
29231 + int oper_path_vector_limit;
29232 + ldp_distribution_mode oper_distribution_mode;
29233 + ldp_loop_detection_mode oper_loop_detection;
29235 + /* these values are learned form the remote peer */
29236 + ldp_distribution_mode remote_distribution_mode;
29237 + mpls_bool remote_loop_detection;
29238 + int remote_path_vector_limit;
29239 + int remote_keepalive;
29240 + int remote_max_pdu;
29241 + mpls_dest remote_dest;
29242 + uint8_t session_name[20]; /* xxx.xxx.xxx.xxx:yyy\0 */
29244 + mpls_bool no_label_resource_sent;
29245 + mpls_bool no_label_resource_recv;
29246 + mpls_bool on_global;
29248 + /* various message and buffers used for tx and rx */
29249 + struct ldp_mesg *keepalive;
29250 + struct ldp_mesg *tx_message;
29251 + struct ldp_buf *tx_buffer;
29253 + /* cached from adj's */
29254 + ldp_role_enum oper_role;
29256 + /* these are config values come from entity */
29257 + ldp_loop_detection_mode cfg_loop_detection_mode;
29258 + ldp_distribution_mode cfg_distribution_mode;
29259 + mpls_bool cfg_remote_in_ttl_less_domain;
29260 + int cfg_label_request_count;
29261 + int cfg_label_request_timer;
29262 + uint16_t cfg_peer_tcp_port;
29263 + int cfg_path_vector_limit;
29264 + int cfg_hop_count_limit;
29265 + int cfg_label_space;
29266 + int cfg_keepalive;
29267 + int cfg_max_pdu;
29269 + /* mesg counters */
29270 + uint32_t mesg_tx;
29271 + uint32_t mesg_rx;
29273 + /* only used by cfg gets */
29274 + uint32_t adj_index;
29276 + mpls_dest local_name;
29277 + mpls_dest remote_name;
29278 +} ldp_session;
29280 +typedef struct ldp_adj {
29281 + MPLS_REFCNT_FIELD;
29282 + MPLS_LIST_ELEM(ldp_adj) _global;
29283 + MPLS_LIST_ELEM(ldp_adj) _session;
29284 + MPLS_LIST_ELEM(ldp_adj) _entity;
29285 + struct ldp_session *session;
29286 + struct ldp_entity *entity;
29287 + mpls_timer_handle hellotime_recv_timer;
29288 + mpls_oper_state_enum state;
29289 + ldp_role_enum role;
29290 + uint32_t index;
29292 + /* these values are learned form the remote peer */
29293 + struct mpls_inet_addr remote_transport_address;
29294 + struct mpls_inet_addr remote_source_address;
29295 + struct mpls_inet_addr remote_lsr_address;
29296 + int remote_label_space;
29297 + int remote_hellotime;
29298 + uint32_t remote_csn;
29300 + /* only used by cfg gets */
29301 + uint32_t session_index;
29302 + uint32_t entity_index;
29303 +} ldp_adj;
29305 +typedef struct ldp_addr {
29306 + MPLS_REFCNT_FIELD;
29307 + MPLS_LIST_ELEM(ldp_addr) _global;
29308 + MPLS_LIST_ELEM(ldp_addr) _if;
29309 + struct ldp_session *session;
29310 + struct ldp_nexthop_list nh_root;
29311 + struct mpls_inet_addr address;
29312 + struct ldp_if *iff;
29314 + /*
29315 + * if an address has a if_handle it is locally attached
29316 + */
29317 + mpls_if_handle if_handle;
29318 + uint32_t index;
29320 + /*
29321 + * only used durring gets
29322 + */
29323 + uint32_t session_index;
29324 + uint32_t nexthop_index;
29325 + uint32_t if_index;
29326 +} ldp_addr;
29328 +struct ldp_outlabel;
29330 +typedef struct ldp_nexthop {
29331 + MPLS_REFCNT_FIELD;
29332 + MPLS_LIST_ELEM(ldp_nexthop) _global;
29333 + MPLS_LIST_ELEM(ldp_nexthop) _fec;
29334 + MPLS_LIST_ELEM(ldp_nexthop) _addr;
29335 + MPLS_LIST_ELEM(ldp_nexthop) _if;
29336 + MPLS_LIST_ELEM(ldp_nexthop) _outlabel;
29337 + struct ldp_outlabel_list outlabel_root;
29338 + struct ldp_fec *fec;
29339 + struct ldp_addr *addr;
29340 + struct ldp_if *iff;
29341 + struct ldp_outlabel *outlabel;
29342 + struct mpls_nexthop info;
29344 + uint32_t index;
29345 +} ldp_nexthop;
29347 +typedef struct ldp_outlabel {
29348 + MPLS_REFCNT_FIELD;
29349 + MPLS_LIST_ELEM(ldp_outlabel) _global;
29350 + MPLS_LIST_ELEM(ldp_outlabel) _session;
29351 + MPLS_LIST_ELEM(ldp_outlabel) _nexthop;
29352 + struct ldp_inlabel_list inlabel_root;
29353 + struct ldp_tunnel_list tunnel_root;
29354 + struct ldp_nexthop_list nh_root;
29355 + uint32_t merge_count;
29356 + struct ldp_attr *attr;
29357 + struct ldp_session *session;
29358 + struct ldp_nexthop *nh;
29359 + struct mpls_outsegment info;
29360 + uint32_t index;
29361 + mpls_bool switching;
29363 + /* only used by get() */
29364 + uint32_t session_index;
29365 + uint32_t nh_index;
29366 + uint32_t attr_index;
29367 +} ldp_outlabel;
29369 +typedef struct ldp_inlabel {
29370 + MPLS_REFCNT_FIELD;
29371 + MPLS_LIST_ELEM(ldp_inlabel) _global;
29372 + MPLS_LIST_ELEM(ldp_inlabel) _outlabel;
29373 + struct mpls_link_list session_root;
29374 + struct mpls_link_list attr_root;
29375 + struct ldp_outlabel *outlabel;
29376 + uint32_t reuse_count;
29377 + uint32_t index;
29378 + struct mpls_insegment info;
29380 + /* only used by get() */
29381 + uint32_t outlabel_index;
29382 +} ldp_inlabel;
29384 +typedef struct ldp_fec {
29385 + MPLS_REFCNT_FIELD;
29386 + MPLS_LIST_ELEM(ldp_fec) _global;
29387 + MPLS_LIST_ELEM(ldp_fec) _inlabel;
29388 + MPLS_LIST_ELEM(ldp_fec) _outlabel;
29389 + MPLS_LIST_ELEM(ldp_fec) _tree;
29390 + MPLS_LIST_ELEM(ldp_fec) _addr;
29391 + MPLS_LIST_ELEM(ldp_fec) _fec;
29392 + MPLS_LIST_ELEM(ldp_fec) _if;
29393 + struct ldp_fs_list fs_root_us;
29394 + struct ldp_fs_list fs_root_ds;
29395 + /* ECMP */
29396 + struct ldp_nexthop_list nh_root;
29397 + struct mpls_fec info;
29398 + mpls_bool is_route;
29399 + uint32_t index;
29400 +} ldp_fec;
29402 +typedef struct ldp_fs {
29403 + struct ldp_attr_list attr_root;
29404 + MPLS_LIST_ELEM(ldp_fs) _fec;
29405 + struct ldp_session *session;
29406 +} ldp_fs;
29408 +typedef struct ldp_attr {
29409 + MPLS_REFCNT_FIELD;
29410 + uint32_t index;
29411 + uint32_t msg_id;
29412 + struct ldp_attr_list us_attr_root;
29413 + struct ldp_attr *ds_attr;
29414 + ldp_lsp_state state;
29415 + mpls_bool ingress;
29416 + mpls_bool filtered;
29417 + mpls_bool in_tree;
29418 + struct ldp_session *session;
29419 + uint32_t attempt_count;
29420 + mpls_timer_handle action_timer;
29421 + ldp_lsp_state action;
29422 + ldp_fec *fec;
29424 + MPLS_LIST_ELEM(ldp_attr) _session;
29425 + MPLS_LIST_ELEM(ldp_attr) _global;
29426 + MPLS_LIST_ELEM(ldp_attr) _ds_attr;
29427 + MPLS_LIST_ELEM(ldp_attr) _fs;
29429 + mplsLdpFecTlv_t fecTlv;
29430 + mplsLdpGenLblTlv_t genLblTlv;
29431 + mplsLdpAtmLblTlv_t atmLblTlv;
29432 + mplsLdpFrLblTlv_t frLblTlv;
29433 + mplsLdpHopTlv_t hopCountTlv;
29434 + mplsLdpPathTlv_t pathVecTlv;
29435 + mplsLdpLblMsgIdTlv_t lblMsgIdTlv;
29436 + mplsLdpLspIdTlv_t lspidTlv;
29437 + mplsLdpTrafficTlv_t trafficTlv;
29438 + mplsLdpStatusTlv_t statusTlv;
29439 + mplsLdpRetMsgTlv_t retMsgTlv;
29441 + uint8_t fecTlvExists:1;
29442 + uint8_t genLblTlvExists:1;
29443 + uint8_t atmLblTlvExists:1;
29444 + uint8_t frLblTlvExists:1;
29445 + uint8_t hopCountTlvExists:1;
29446 + uint8_t pathVecTlvExists:1;
29447 + uint8_t lblMsgIdTlvExists:1;
29448 + uint8_t lspidTlvExists:1;
29449 + uint8_t trafficTlvExists:1;
29450 + uint8_t statusTlvExists:1;
29451 + uint8_t retMsgTlvExists:1;
29453 + struct ldp_outlabel *outlabel;
29454 + struct ldp_inlabel *inlabel;
29456 + /* only used for get() */
29457 + uint32_t inlabel_index;
29458 + uint32_t outlabel_index;
29459 + uint32_t session_index;
29460 +} ldp_attr;
29462 +typedef struct ldp_resource {
29463 + MPLS_REFCNT_FIELD;
29464 + MPLS_LIST_ELEM(ldp_resource) _global;
29465 + struct ldp_tunnel *tunnel;
29466 + uint32_t index;
29467 + uint32_t max_rate;
29468 + uint32_t mean_rate;
29469 + uint32_t burst_size;
29470 +} ldp_resource;
29472 +typedef struct ldp_hop {
29473 + MPLS_REFCNT_FIELD;
29474 + MPLS_LIST_ELEM(ldp_hop) _hop_list;
29475 + struct ldp_hop_list *hop_list;
29476 + uint32_t index;
29477 + uint32_t hop_list_index;
29478 + uint32_t path_option;
29479 + mpls_inet_addr addr;
29480 + uint32_t type;
29481 +} ldp_hop;
29483 +typedef struct ldp_hop_list {
29484 + MPLS_REFCNT_FIELD;
29485 + MPLS_LIST_ELEM(ldp_hop_list) _global;
29486 + struct _ldp_hop_list hop;
29487 + struct ldp_tunnel *tunnel;
29488 + uint32_t index;
29489 +} ldp_hop_list;
29491 +typedef struct ldp_tunnel {
29492 + MPLS_REFCNT_FIELD;
29493 + MPLS_LIST_ELEM(ldp_tunnel) _global;
29494 + MPLS_LIST_ELEM(ldp_tunnel) _outlabel;
29495 + uint32_t index;
29496 + mpls_inet_addr ingress_lsrid;
29497 + ldp_addr egress_lsrid;
29498 + char name[MPLS_MAX_IF_NAME];
29499 + mpls_bool is_interface;
29500 + uint32_t outlabel_index;
29501 + struct ldp_outlabel *outlabel;
29502 + uint32_t setup_prio;
29503 + uint32_t hold_prio;
29504 + uint32_t instance_prio;
29505 + uint32_t resource_index;
29506 + struct ldp_resource *resource;
29507 + uint32_t hop_list_index;
29508 + struct ldp_hop_list *hop_list;
29509 + ldp_fec fec;
29510 + mpls_admin_state_enum admin_state;
29512 + uint32_t primary_instance;
29513 + uint32_t any_affinity;
29514 + uint32_t all_affinity;
29515 + uint32_t no_all_affinity;
29516 + uint32_t path_in_use;
29517 + uint32_t protocol;
29518 + mpls_bool local_protect;
29519 + uint32_t session_attr;
29520 + uint32_t owner;
29521 +} ldp_tunnel;
29523 +typedef void (*ldp_tree_callback) (void *);
29525 +#endif
29526 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_tunnel.c quagga-mpls/ldpd/ldp_tunnel.c
29527 --- quagga/ldpd/ldp_tunnel.c 1969-12-31 18:00:00.000000000 -0600
29528 +++ quagga-mpls/ldpd/ldp_tunnel.c 2006-08-24 22:46:16.000000000 -0500
29529 @@ -0,0 +1,146 @@
29532 + * Copyright (C) James R. Leu 2001
29533 + * jleu@mindspring.com
29535 + * This software is covered under the LGPL, for more
29536 + * info check out http://www.gnu.org/copyleft/lgpl.html
29537 + */
29539 +#include "ldp_struct.h"
29540 +#include "ldp_tunnel.h"
29541 +#include "ldp_hop_list.h"
29542 +#include "ldp_resource.h"
29543 +#include "ldp_outlabel.h"
29545 +#include "mpls_assert.h"
29546 +#include "mpls_mm_impl.h"
29547 +#include "mpls_trace_impl.h"
29549 +static uint32_t _ldp_tunnel_next_index = 1;
29551 +ldp_tunnel *ldp_tunnel_create()
29553 + ldp_tunnel *t = (ldp_tunnel *) mpls_malloc(sizeof(ldp_tunnel));
29555 + if (t) {
29556 + memset(t, 0, sizeof(ldp_tunnel));
29557 + MPLS_REFCNT_INIT(t, 0);
29558 + MPLS_LIST_ELEM_INIT(t, _global);
29559 + MPLS_LIST_ELEM_INIT(t, _outlabel);
29561 + t->index = _ldp_tunnel_get_next_index();
29563 + return t;
29566 +void ldp_tunnel_delete(ldp_tunnel * t)
29568 + // LDP_PRINT(g->user_data,"tunnel delete\n");
29569 + MPLS_REFCNT_ASSERT(t, 0);
29570 + mpls_free(t);
29573 +uint32_t _ldp_tunnel_get_next_index()
29575 + uint32_t retval = _ldp_tunnel_next_index;
29577 + _ldp_tunnel_next_index++;
29578 + if (retval > _ldp_tunnel_next_index) {
29579 + _ldp_tunnel_next_index = 1;
29581 + return retval;
29584 +mpls_bool ldp_tunnel_is_active(ldp_tunnel * t)
29586 + if (t->admin_state == MPLS_ADMIN_ENABLE) {
29587 + return MPLS_BOOL_TRUE;
29589 + return MPLS_BOOL_FALSE;
29592 +mpls_bool ldp_tunnel_is_ready(ldp_tunnel * t)
29594 + return MPLS_BOOL_TRUE;
29597 +mpls_return_enum ldp_tunnel_add_resource(ldp_tunnel * t, ldp_resource * r)
29599 + if (t && r) {
29600 + MPLS_REFCNT_HOLD(r);
29601 + MPLS_ASSERT(t->resource == NULL);
29602 + t->resource = r;
29603 + _ldp_resource_add_tunnel(r, t);
29604 + return MPLS_SUCCESS;
29606 + return MPLS_FAILURE;
29609 +mpls_return_enum ldp_tunnel_del_resource(ldp_tunnel * t)
29611 + if (t && t->resource) {
29612 + _ldp_resource_del_tunnel(t->resource);
29613 + MPLS_REFCNT_RELEASE(t->resource, ldp_resource_delete);
29614 + t->resource = NULL;
29615 + return MPLS_SUCCESS;
29617 + return MPLS_FAILURE;
29620 +mpls_return_enum ldp_tunnel_add_hop_list(ldp_tunnel * t, ldp_hop_list * h)
29622 + if (t && h) {
29623 + MPLS_REFCNT_HOLD(h);
29624 + MPLS_ASSERT(t->hop_list == NULL);
29625 + t->hop_list = h;
29626 + _ldp_hop_list_add_tunnel(h, t);
29627 + return MPLS_SUCCESS;
29629 + return MPLS_FAILURE;
29632 +mpls_return_enum ldp_tunnel_del_hop_list(ldp_tunnel * t)
29634 + if (t && t->hop_list) {
29635 + _ldp_hop_list_del_tunnel(t->hop_list);
29636 + MPLS_REFCNT_RELEASE(t->hop_list, ldp_hop_list_delete);
29637 + t->hop_list = NULL;
29638 + return MPLS_SUCCESS;
29640 + return MPLS_FAILURE;
29643 +mpls_return_enum ldp_tunnel_add_outlabel(ldp_tunnel * t, ldp_outlabel * o)
29645 + if (t && o) {
29646 + MPLS_REFCNT_HOLD(o);
29647 + MPLS_ASSERT(t->outlabel == NULL);
29648 + t->outlabel = o;
29649 + _ldp_outlabel_add_tunnel(o, t);
29650 + return MPLS_SUCCESS;
29652 + return MPLS_FAILURE;
29655 +mpls_return_enum ldp_tunnel_del_outlabel(ldp_global * g, ldp_tunnel * t)
29657 + if (t && t->outlabel) {
29658 + _ldp_outlabel_del_tunnel(t->outlabel, t);
29659 + MPLS_REFCNT_RELEASE2(g, t->outlabel, ldp_outlabel_delete);
29660 + t->outlabel = NULL;
29661 + return MPLS_SUCCESS;
29663 + return MPLS_FAILURE;
29666 +mpls_return_enum ldp_tunnel_startup(ldp_global * global, ldp_tunnel * tunnel)
29668 + return MPLS_FAILURE;
29671 +mpls_return_enum ldp_tunnel_shutdown(ldp_global * global, ldp_tunnel * tunnel,
29672 + int flag)
29674 + return MPLS_SUCCESS;
29676 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_tunnel.h quagga-mpls/ldpd/ldp_tunnel.h
29677 --- quagga/ldpd/ldp_tunnel.h 1969-12-31 18:00:00.000000000 -0600
29678 +++ quagga-mpls/ldpd/ldp_tunnel.h 2006-08-24 22:46:34.000000000 -0500
29679 @@ -0,0 +1,43 @@
29682 + * Copyright (C) James R. Leu 2001
29683 + * jleu@mindspring.com
29685 + * This software is covered under the LGPL, for more
29686 + * info check out http://www.gnu.org/copyleft/lgpl.html
29687 + */
29689 +#ifndef _LDP_TUNNEL_H_
29690 +#define _LDP_TUNNEL_H_
29692 +#include "ldp_struct.h"
29694 +extern ldp_tunnel *ldp_tunnel_create();
29695 +extern void ldp_tunnel_delete(ldp_tunnel * t);
29696 +extern uint32_t _ldp_tunnel_get_next_index();
29698 +extern mpls_return_enum ldp_tunnel_add_resource(ldp_tunnel * t,
29700 + ldp_resource * r);
29701 +extern mpls_return_enum ldp_tunnel_del_resource(ldp_tunnel * t);
29703 +extern mpls_return_enum ldp_tunnel_add_hop_list(ldp_tunnel * t,
29705 + ldp_hop_list * h);
29706 +extern mpls_return_enum ldp_tunnel_del_hop_list(ldp_tunnel * t);
29708 +extern mpls_return_enum ldp_tunnel_add_outlabel(ldp_tunnel * t,
29710 + ldp_outlabel * o);
29711 +extern mpls_return_enum ldp_tunnel_del_outlabel(ldp_global * g, ldp_tunnel * t);
29713 +extern mpls_bool ldp_tunnel_is_active(ldp_tunnel * t);
29714 +extern mpls_bool ldp_tunnel_is_ready(ldp_tunnel * t);
29716 +extern mpls_return_enum ldp_tunnel_startup(ldp_global * global,
29718 + ldp_tunnel * tunnel);
29719 +extern mpls_return_enum ldp_tunnel_shutdown(ldp_global * global,
29720 + ldp_tunnel * tunnel, int flag);
29722 +#endif
29723 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_vty.c quagga-mpls/ldpd/ldp_vty.c
29724 --- quagga/ldpd/ldp_vty.c 1969-12-31 18:00:00.000000000 -0600
29725 +++ quagga-mpls/ldpd/ldp_vty.c 2008-03-24 20:19:35.000000000 -0500
29726 @@ -0,0 +1,2602 @@
29727 +#include <zebra.h>
29729 +#include "zclient.h"
29730 +#include "vty.h"
29731 +#include "command.h"
29732 +#include "table.h"
29734 +#include "ldp.h"
29735 +#include "ldp_cfg.h"
29736 +#include "ldp_vty.h"
29737 +#include "ldp_interface.h"
29738 +#include "ldp_struct.h"
29739 +#include "ldp_remote_peer.h"
29740 +#include "ldp_zebra.h"
29742 +#include "impl_mpls.h"
29744 +uint32_t ldp_traceflags = 0;
29745 +uint8_t trace_buffer[16834];
29746 +int trace_buffer_len = 0;
29748 +static const char *session_state[6] = { "NONE", "NON-EXIST", "INIT",
29749 + "OPENSENT", "OPENRECV", "OPERATIONAL" };
29750 +// static char *adj_role[3] = { "INVALID", "PASSIVE", "ACTIVE" };
29751 +static const char *attr_state[12] = { "REQ_RECV", "REQ_SENT", "MAP_RECV",
29752 + "MAP_SENT", "WITH_SENT", "WITH_RECV",
29753 + "NO_LABEL_RESOURCE_SENT", "NO_LABEL_RESOURCE_RECV",
29754 + "ABORT_SENT", "ABORT_RECV", "NOTIF_SENT",
29755 + "NOTIF_RECV" };
29756 +// static char *oper_state[2] = { "UP", "DOWN" };
29757 +static const char *control_mode[3] = { "UNKNOWN", "INDEPENDENT", "ORDERED" };
29758 +static const char *retention_mode[3] = { "UNKNOWN", "LIBERAL", "CONSERVATIVE" };
29759 +static const char *repair_mode[3] = { "UNKNOWN", "LOCAL", "GLOBAL" };
29760 +static const char *loop_detect_mode[5] = { "NONE", "HOPCOUNT", "PATHVECTOR",
29761 + "HOPCOUNT PATHVECTOR", "OTHER" };
29762 +const char *bool[2] = { "FALSE", "TRUE" };
29763 +static const char *admin_state[3] = { "NONE", "ENABLED", "DISABLED" };
29764 +static const char *distribution_mode[2] = { "UNSOLICITED", "ONDEMAND" };
29766 +extern struct zclient *zclient;
29768 +#if 0
29769 +DEFUN (mpls_vfi,
29770 + mpls_vfi_cmd,
29771 + "l2 vfi WORD manual",
29772 + "Global VPLS configuration\n"
29773 + "VFI Configuration\n"
29774 + "VFI NAME\n"
29775 + "Manual Peer Discovery\n")
29779 +DEFUN (vfi_vpn_id,
29780 + vfi_vpn_id_cmd,
29781 + "vpn id NUMBER",
29782 + "VPLS VPN Configuration\n"
29783 + "VPN Identifier\n"
29784 + "<1-4096>\n")
29788 +DEFUN (vfi_neighbor,
29789 + vfi_neighbor_cmd,
29790 + "neighbor IPADDRESS",
29791 + "VPLS Neighbor Configuration\n"
29792 + "IP address of Neighbor\n")
29796 +DEFUN (no_mpls_vfi,
29797 + no_mpls_vfi_cmd,
29798 + "no l2 vfi WORD manual",
29799 + NO_STR
29800 + "Global VPLS configuration\n"
29801 + "VFI Configuration\n"
29802 + "VFI NAME\n"
29803 + "Manual Peer Discovery\n")
29807 +DEFUN (no_vfi_vpn_id,
29808 + no_vfi_vpn_id_cmd,
29809 + "no vpn id NUMBER",
29810 + NO_STR
29811 + "VPLS VPN Configuration\n"
29812 + "VPN Identifier\n"
29813 + "<1-4096>\n")
29817 +DEFUN (no_vfi_neighbor,
29818 + no_vfi_neighbor_cmd,
29819 + "no neighbor IPADDRESS",
29820 + NO_STR
29821 + "VPLS Neighbor Configuration\n"
29822 + "IP address of Neighbor\n")
29826 +show mpls l2transport vc vcid 200 detail
29827 +Local interface: Vi1 up, line protocol up, VFI
29828 + Destination address: 22.22.22.22, VC ID: 200 VC status: up
29829 + Tunnel label: imp-null, next hop point2point
29830 + Output interface: PO2/1, imposed label stack {16}
29831 + MPLS VC labels: local 18, remote 16
29832 + Group ID: local 200, remote 200
29833 + MTU: local 1500, remote 1500
29834 + Remote interface description:
29835 + Sequencing: received disabled, send disabled
29836 + VC statistics:
29837 + packet totals: receive 0, send 0
29838 + byte totals: receive 0, send 0
29839 + packet drops: receive 0, send 0
29841 +DEFUN (show_mpls_l2transport_vc,
29842 + show_mpls_l2transport_vc_cmd,
29843 + "show mpls l2transport vc",
29844 + "Show Commands",
29845 + "Multiprotocol Label Switching show commands\n"
29846 + "Layer 2 over MPLS show commands\n"
29847 + "Virtual Circuit status\n")
29849 +Local Intf Local Circuit Dest Address VC ID Status
29850 +---------- ------------- ------------ ----- ------
29851 +Vi1 VFI 22.22.22.22 100 DOWN
29852 +Vi1 VFI 33.33.33.33 100 UP
29856 +DEFUN (show_vfi,
29857 + show_vfi_cmd,
29858 + "show vfi WORD",
29859 + "Show Commands",
29860 + "Virtual Private LAN Service show commands\n"
29861 + "VFI Name\n")
29863 +VFI name: VPLSA, state: up
29864 + Local attachment circuits:
29865 + Vlan100
29866 + Neighbors connected via pseudowires:
29867 + 22.22.22.22 33.33.33.33
29869 +#endif
29871 +DEFUN (mpls_ldp,
29872 + mpls_ldp_cmd,
29873 + "mpls ldp",
29874 + "Global MPLS configuration\n"
29875 + "Dynamic Label distribution via LDP\n")
29877 + vty->node = LDP_NODE;
29878 + vty->index = ldp_get();
29879 + if (!vty->index) {
29880 + if (!(vty->index = ldp_new())) {
29881 + vty_out (vty, "Unable to create LDP instance.%s", VTY_NEWLINE);
29882 + return CMD_WARNING;
29885 + return CMD_SUCCESS;
29888 +DEFUN (no_mpls_ldp,
29889 + no_mpls_ldp_cmd,
29890 + "no mpls ldp",
29891 + NO_STR
29892 + "MPLS configuration\n"
29893 + "Dynamic Label distribution via LDP\n")
29895 + struct ldp *ldp = ldp_get();
29897 + if (!ldp) {
29898 + vty_out (vty, "There isn't active an LDP instance.%s", VTY_NEWLINE);
29899 + return CMD_WARNING;
29902 + ldp_finish(ldp);
29903 + return CMD_SUCCESS;
29906 +DEFUN (ldp_lsrid,
29907 + ldp_lsrid_cmd,
29908 + "lsr-id A.B.C.D",
29909 + "LDP Label Switch Router Identifier\n"
29910 + "IP Address\n")
29912 + struct ldp *ldp = (struct ldp*)vty->index;
29914 + ldp->lsr_id_is_static = MPLS_BOOL_TRUE;
29916 + ldp_admin_state_start(ldp);
29917 + do_ldp_router_id_update(ldp, ntohl(inet_addr(argv[0])));
29918 + ldp_admin_state_finish(ldp);
29920 + return CMD_SUCCESS;
29923 +DEFUN (no_ldp_lsrid,
29924 + no_ldp_lsrid_cmd,
29925 + "no lsr-id",
29926 + NO_STR
29927 + "LDP LSRID\n")
29929 + struct ldp *ldp = (struct ldp*)vty->index;
29931 + ldp->lsr_id_is_static = MPLS_BOOL_FALSE;
29933 + ldp_admin_state_start(ldp);
29934 + do_ldp_router_id_update(ldp, ntohl(router_id.u.prefix4.s_addr));
29935 + ldp_admin_state_finish(ldp);
29937 + return CMD_SUCCESS;
29940 +DEFUN (ldp_disable,
29941 + ldp_disable_cmd,
29942 + "disable",
29943 + "Disable\n")
29945 + struct ldp *ldp = (struct ldp*)vty->index;
29947 + ldp_admin_state_start(ldp);
29948 + ldp->admin_up = MPLS_BOOL_FALSE;
29949 + ldp_admin_state_finish(ldp);
29951 + return CMD_SUCCESS;
29954 +DEFUN (no_ldp_disable,
29955 + no_ldp_disable_cmd,
29956 + "no disable",
29957 + NO_STR
29958 + "Disable\n")
29960 + struct ldp *ldp = (struct ldp*)vty->index;
29962 + ldp_admin_state_start(ldp);
29963 + ldp->admin_up = MPLS_BOOL_TRUE;
29964 + ldp_admin_state_finish(ldp);
29966 + return CMD_SUCCESS;
29969 +DEFUN (ldp_transport_address,
29970 + ldp_transport_address_cmd,
29971 + "transport-address (interface|lsr-id|IPADDRESS|NAME)",
29972 + "global transport address\n"
29973 + "use the IP address on configured interfaces\n"
29974 + "use the LSR-ID\n"
29975 + "specify an IP address\n"
29976 + "name of interface from which to use the primary IP address\n")
29978 + struct ldp *ldp = (struct ldp*)vty->index;
29979 + struct ldp_interface *li;
29980 + struct listnode *node;
29981 + struct interface *ifp;
29982 + unsigned int addr = 0;
29983 + ldp_entity e;
29984 + ldp_global g;
29986 + g.transport_address.type = MPLS_FAMILY_NONE;
29987 + g.transport_address.u.ipv4 = 0;
29989 + if (!strncmp(argv[0], "interface", 9)) {
29990 + ldp->trans_addr = LDP_TRANS_ADDR_INTERFACE;
29991 + } else if (!strncmp(argv[0], "lsr-id", 6)) {
29992 + ldp->trans_addr = LDP_TRANS_ADDR_LSRID;
29993 + g.transport_address.type = MPLS_FAMILY_IPV4;
29994 + g.transport_address.u.ipv4 = ntohl(router_id.u.prefix4.s_addr);
29995 + } else if ((addr = inet_addr(argv[0])) != INADDR_NONE) {
29996 + ldp->trans_addr = LDP_TRANS_ADDR_STATIC_IP;
29997 + g.transport_address.type = MPLS_FAMILY_IPV4;
29998 + g.transport_address.u.ipv4 = ntohl(addr);
29999 + } else {
30000 + ifp = if_lookup_by_name(argv[0]);
30001 + ldp->trans_addr = LDP_TRANS_ADDR_STATIC_INTERFACE;
30002 + strncpy(ldp->trans_addr_ifname, argv[0], IFNAMSIZ + 1);
30003 + if (ifp) {
30004 + g.transport_address.type = MPLS_FAMILY_IPV4;
30005 + g.transport_address.u.ipv4 = ntohl(if_ipv4_src_address (ifp));
30009 + for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
30010 + li = ifp->info;
30012 + if (ldp->trans_addr == LDP_TRANS_ADDR_INTERFACE) {
30013 + li->entity.transport_address.u.ipv4 = ntohl(if_ipv4_src_address (ifp));
30014 + } else {
30015 + li->entity.transport_address.u.ipv4 = 0;
30017 + li->entity.transport_address.type =
30018 + li->entity.transport_address.u.ipv4 ?
30019 + MPLS_FAMILY_IPV4 : MPLS_FAMILY_NONE;
30021 + if (li->entity.index) {
30022 + ldp_interface_admin_state_start(li);
30023 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_TRANS_ADDR);
30024 + ldp_interface_admin_state_finish(li);
30028 + ldp_admin_state_start(ldp);
30029 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_TRANS_ADDR);
30030 + ldp_admin_state_finish(ldp);
30032 + return CMD_SUCCESS;
30035 +DEFUN (no_ldp_transport_address,
30036 + no_ldp_transport_address_cmd,
30037 + "no transport-address",
30038 + NO_STR
30039 + "No globally specified transport address\n")
30041 + struct ldp *ldp = (struct ldp*)vty->index;
30042 + ldp_global g;
30043 + struct ldp_interface *li;
30044 + struct listnode *node;
30045 + struct interface *ifp;
30047 + ldp->trans_addr = LDP_TRANS_ADDR_NONE;
30048 + memset(ldp->trans_addr_ifname, 0, IFNAMSIZ + 1);
30050 + g.transport_address.type = MPLS_FAMILY_NONE;
30051 + g.transport_address.u.ipv4 = 0;
30053 + for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
30054 + li = ifp->info;
30056 + li->entity.transport_address.u.ipv4 = 0;
30057 + li->entity.transport_address.type = MPLS_FAMILY_NONE;
30059 + if (li->entity.index) {
30060 + ldp_interface_admin_state_start(li);
30061 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_TRANS_ADDR);
30062 + ldp_interface_admin_state_finish(li);
30065 + ldp_admin_state_start(ldp);
30066 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_TRANS_ADDR);
30067 + ldp_admin_state_finish(ldp);
30069 + return CMD_SUCCESS;
30072 +DEFUN (ldp_lsp_control_mode,
30073 + ldp_lsp_control_mode_cmd,
30074 + "lsp-control-mode (independent|ordered)",
30075 + "control mode\n"
30076 + "independent or ordered control mode\n")
30078 + struct ldp *ldp = (struct ldp*)vty->index;
30079 + ldp_global g;
30081 + if (!strcmp(argv[0],"independent")) {
30082 + g.lsp_control_mode = LDP_CONTROL_INDEPENDENT;
30083 + } else if (!strcmp(argv[0],"ordered")) {
30084 + g.lsp_control_mode = LDP_CONTROL_ORDERED;
30085 + } else {
30086 + return CMD_WARNING;
30089 + ldp_admin_state_start(ldp);
30090 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_CONTROL_MODE);
30091 + ldp_admin_state_finish(ldp);
30093 + return CMD_SUCCESS;
30096 +DEFUN (no_ldp_lsp_control_mode,
30097 + no_ldp_lsp_control_mode_cmd,
30098 + "no lsp-control-mode",
30099 + NO_STR
30100 + "control mode\n")
30102 + struct ldp *ldp = (struct ldp*)vty->index;
30103 + ldp_global g;
30105 + g.lsp_control_mode = LDP_GLOBAL_DEF_CONTROL_MODE;
30107 + ldp_admin_state_start(ldp);
30108 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_CONTROL_MODE);
30109 + ldp_admin_state_finish(ldp);
30111 + return CMD_SUCCESS;
30114 +DEFUN (ldp_label_retention_mode,
30115 + ldp_label_retention_mode_cmd,
30116 + "label-retention-mode (liberal|conservative)",
30117 + "label retention mode\n"
30118 + "liberal or conservative retention mode\n")
30120 + struct ldp *ldp = (struct ldp*)vty->index;
30121 + ldp_global g;
30123 + if (!strcmp(argv[0],"liberal")) {
30124 + g.label_retention_mode = LDP_RETENTION_LIBERAL;
30125 + } else if (!strcmp(argv[0],"conservative")) {
30126 + g.label_retention_mode = LDP_RETENTION_CONSERVATIVE;
30127 + } else {
30128 + return CMD_WARNING;
30131 + ldp_admin_state_start(ldp);
30132 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_RETENTION_MODE);
30133 + ldp_admin_state_finish(ldp);
30135 + return CMD_SUCCESS;
30138 +DEFUN (no_ldp_label_retention_mode,
30139 + no_ldp_label_retention_mode_cmd,
30140 + "no label-retention-mode",
30141 + NO_STR
30142 + "label retiontion mode\n")
30144 + struct ldp *ldp = (struct ldp*)vty->index;
30145 + ldp_global g;
30147 + g.label_retention_mode = LDP_GLOBAL_DEF_RETENTION_MODE;
30149 + ldp_admin_state_start(ldp);
30150 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_RETENTION_MODE);
30151 + ldp_admin_state_finish(ldp);
30153 + return CMD_SUCCESS;
30156 +DEFUN (ldp_lsp_repair_mode,
30157 + ldp_lsp_repair_mode_cmd,
30158 + "lsp-repair-mode (local|global)",
30159 + "repair mode\n"
30160 + "local or global repair mode\n")
30162 + struct ldp *ldp = (struct ldp*)vty->index;
30163 + ldp_global g;
30165 + if (!strcmp(argv[0],"local")) {
30166 + g.lsp_repair_mode = LDP_REPAIR_LOCAL;
30167 + } else if (!strcmp(argv[0],"global")) {
30168 + g.lsp_repair_mode = LDP_REPAIR_GLOBAL;
30169 + } else {
30170 + return CMD_WARNING;
30172 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_REPAIR_MODE);
30174 + return CMD_SUCCESS;
30177 +DEFUN (no_ldp_lsp_repair_mode,
30178 + no_ldp_lsp_repair_mode_cmd,
30179 + "no lsp-repair-mode",
30180 + NO_STR
30181 + "repair mode\n")
30183 + struct ldp *ldp = (struct ldp*)vty->index;
30184 + ldp_global g;
30186 + g.lsp_repair_mode = LDP_GLOBAL_DEF_REPAIR_MODE;
30187 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_REPAIR_MODE);
30189 + return CMD_SUCCESS;
30192 +DEFUN (ldp_propogate_release,
30193 + ldp_propogate_release_cmd,
30194 + "propagate-release",
30195 + "propagate release\n")
30197 + struct ldp *ldp = (struct ldp*)vty->index;
30198 + ldp_global g;
30200 + g.propagate_release = MPLS_BOOL_TRUE;
30201 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_PROPOGATE_RELEASE);
30203 + return CMD_SUCCESS;
30206 +DEFUN (no_ldp_propogate_release,
30207 + no_ldp_propogate_release_cmd,
30208 + "no propagate-release",
30209 + NO_STR
30210 + "propagate release\n")
30212 + struct ldp *ldp = (struct ldp*)vty->index;
30213 + ldp_global g;
30215 + g.propagate_release = MPLS_BOOL_FALSE;
30216 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_PROPOGATE_RELEASE);
30218 + return CMD_SUCCESS;
30221 +DEFUN (ldp_label_merge,
30222 + ldp_label_merge_cmd,
30223 + "label-merge",
30224 + "label merge\n")
30226 + struct ldp *ldp = (struct ldp*)vty->index;
30227 + ldp_global g;
30229 + g.label_merge = MPLS_BOOL_TRUE;
30231 + ldp_admin_state_start(ldp);
30232 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_LABEL_MERGE);
30233 + ldp_admin_state_finish(ldp);
30235 + return CMD_SUCCESS;
30238 +DEFUN (no_ldp_label_merge,
30239 + no_ldp_label_merge_cmd,
30240 + "no label-merge",
30241 + NO_STR
30242 + "label merge\n")
30244 + struct ldp *ldp = (struct ldp*)vty->index;
30245 + ldp_global g;
30247 + g.label_merge = MPLS_BOOL_FALSE;
30249 + ldp_admin_state_start(ldp);
30250 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_LABEL_MERGE);
30251 + ldp_admin_state_finish(ldp);
30253 + return CMD_SUCCESS;
30256 +DEFUN (ldp_global_loop_detection_mode,
30257 + ldp_global_loop_detection_mode_cmd,
30258 + "loop-detection-mode (hop|path|both)",
30259 + "loop detection\n"
30260 + "Path Vector, Hop Count, or both\n")
30262 + struct ldp *ldp = (struct ldp*)vty->index;
30263 + ldp_global g;
30265 + if (!strncmp(argv[0],"hop",3)) {
30266 + g.loop_detection_mode = LDP_LOOP_HOPCOUNT;
30267 + } else if (!strncmp(argv[0],"path",4)) {
30268 + g.loop_detection_mode = LDP_LOOP_PATHVECTOR;
30269 + } else if (!strncmp(argv[0],"both",4)) {
30270 + g.loop_detection_mode = LDP_LOOP_HOPCOUNT_PATHVECTOR;
30271 + } else {
30272 + return CMD_WARNING;
30274 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_LOOP_DETECTION_MODE);
30276 + return CMD_SUCCESS;
30279 +DEFUN (no_ldp_loop_detection_mode,
30280 + no_ldp_loop_detection_mode_cmd,
30281 + "no loop-detection-mode (path|hop|both)",
30282 + NO_STR
30283 + "loop detection\n")
30285 + struct ldp *ldp = (struct ldp*)vty->index;
30286 + ldp_global g;
30288 + g.loop_detection_mode = LDP_LOOP_NONE;
30289 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_LOOP_DETECTION_MODE);
30291 + return CMD_SUCCESS;
30294 +DEFUN (ldp_ttl_less_domain,
30295 + ldp_ttl_less_domain_cmd,
30296 + "ttl-less-domain",
30297 + "TTL-less domain\n")
30299 + struct ldp *ldp = (struct ldp*)vty->index;
30300 + ldp_global g;
30302 + g.ttl_less_domain = MPLS_BOOL_TRUE;
30303 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_TTLLESS_DOMAIN);
30305 + return CMD_SUCCESS;
30308 +DEFUN (no_ldp_ttl_less_domain,
30309 + no_ldp_ttl_less_domain_cmd,
30310 + "no ttl-less-domain",
30311 + NO_STR
30312 + "TTL-less domain\n")
30314 + struct ldp *ldp = (struct ldp*)vty->index;
30315 + ldp_global g;
30317 + g.ttl_less_domain = MPLS_BOOL_FALSE;
30318 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_TTLLESS_DOMAIN);
30320 + return CMD_SUCCESS;
30323 +DEFUN (ldp_local_tcp_port,
30324 + ldp_local_tcp_port_cmd,
30325 + "local-tcp-port <1-65535>",
30326 + "local TCP port\n"
30327 + "TCP port number\n")
30329 + struct ldp *ldp = (struct ldp*)vty->index;
30330 + ldp_global g;
30332 + g.local_tcp_port = atoi(argv[0]);
30334 + ldp_admin_state_start(ldp);
30335 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_LOCAL_TCP_PORT);
30336 + ldp_admin_state_finish(ldp);
30338 + return CMD_SUCCESS;
30341 +DEFUN (no_ldp_local_tcp_port,
30342 + no_ldp_local_tcp_port_cmd,
30343 + "no local-tcp-port",
30344 + NO_STR
30345 + "local TCP port\n")
30347 + struct ldp *ldp = (struct ldp*)vty->index;
30348 + ldp_global g;
30350 + g.local_tcp_port = LDP_GLOBAL_DEF_LOCAL_TCP_PORT;
30352 + ldp_admin_state_start(ldp);
30353 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_LOCAL_TCP_PORT);
30354 + ldp_admin_state_finish(ldp);
30356 + return CMD_SUCCESS;
30359 +DEFUN (ldp_local_udp_port,
30360 + ldp_local_udp_port_cmd,
30361 + "local-udp-port <1-65535>",
30362 + "local UDP port\n"
30363 + "UDP port number\n")
30365 + struct ldp *ldp = (struct ldp*)vty->index;
30366 + ldp_global g;
30368 + g.local_udp_port = atoi(argv[0]);
30370 + ldp_admin_state_start(ldp);
30371 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_LOCAL_UDP_PORT);
30372 + ldp_admin_state_finish(ldp);
30374 + return CMD_SUCCESS;
30377 +DEFUN (no_ldp_local_udp_port,
30378 + no_ldp_local_udp_port_cmd,
30379 + "no local-udp-port",
30380 + NO_STR
30381 + "local UDP port\n")
30383 + struct ldp *ldp = (struct ldp*)vty->index;
30384 + ldp_global g;
30386 + g.local_udp_port = LDP_GLOBAL_DEF_LOCAL_UDP_PORT;
30388 + ldp_admin_state_start(ldp);
30389 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_LOCAL_UDP_PORT);
30390 + ldp_admin_state_finish(ldp);
30392 + return CMD_SUCCESS;
30395 +DEFUN (ldp_trace_address,
30396 + ldp_trace_address_cmd,
30397 + "trace address",
30398 + "LDP debugging\n"
30399 + "Address PDUs\n")
30401 + ldp_traceflags |= LDP_TRACE_FLAG_ADDRESS;
30402 + return CMD_SUCCESS;
30405 +DEFUN (ldp_trace_binding,
30406 + ldp_trace_binding_cmd,
30407 + "trace binding",
30408 + "LDP debugging\n"
30409 + "Label Bindings\n")
30411 + ldp_traceflags |= LDP_TRACE_FLAG_BINDING;
30412 + return CMD_SUCCESS;
30415 +DEFUN (ldp_trace_debug,
30416 + ldp_trace_debug_cmd,
30417 + "trace debug",
30418 + "LDP debugging\n"
30419 + "Debug Messages\n")
30421 + ldp_traceflags |= LDP_TRACE_FLAG_DEBUG;
30422 + return CMD_SUCCESS;
30425 +DEFUN (ldp_trace_error,
30426 + ldp_trace_error_cmd,
30427 + "trace error",
30428 + "LDP debugging\n"
30429 + "Error Conditions\n")
30431 + ldp_traceflags |= LDP_TRACE_FLAG_ERROR;
30432 + return CMD_SUCCESS;
30435 +DEFUN (ldp_trace_event,
30436 + ldp_trace_event_cmd,
30437 + "trace event",
30438 + "LDP debugging\n"
30439 + "LDP Events\n")
30441 + ldp_traceflags |= LDP_TRACE_FLAG_EVENT;
30442 + return CMD_SUCCESS;
30445 +DEFUN (ldp_trace_general,
30446 + ldp_trace_general_cmd,
30447 + "trace general",
30448 + "LDP debugging\n"
30449 + "General Messages\n")
30451 + ldp_traceflags |= LDP_TRACE_FLAG_GENERAL;
30452 + return CMD_SUCCESS;
30455 +DEFUN (ldp_trace_init,
30456 + ldp_trace_init_cmd,
30457 + "trace init",
30458 + "LDP debugging\n"
30459 + "Init PDUs\n")
30461 + ldp_traceflags |= LDP_TRACE_FLAG_INIT;
30462 + return CMD_SUCCESS;
30465 +DEFUN (ldp_trace_label,
30466 + ldp_trace_label_cmd,
30467 + "trace label",
30468 + "LDP debugging\n"
30469 + "Label PDUs\n")
30471 + ldp_traceflags |= LDP_TRACE_FLAG_LABEL;
30472 + return CMD_SUCCESS;
30475 +DEFUN (ldp_trace_normal,
30476 + ldp_trace_normal_cmd,
30477 + "trace normal",
30478 + "LDP debugging\n"
30479 + "Normal Messages\n")
30481 + ldp_traceflags |= LDP_TRACE_FLAG_NORMAL;
30482 + return CMD_SUCCESS;
30485 +DEFUN (ldp_trace_notif,
30486 + ldp_trace_notif_cmd,
30487 + "trace notification",
30488 + "LDP debugging\n"
30489 + "Notification PDUs\n")
30491 + ldp_traceflags |= LDP_TRACE_FLAG_NOTIF;
30492 + return CMD_SUCCESS;
30495 +DEFUN (ldp_trace_packet_dump,
30496 + ldp_trace_packet_dump_cmd,
30497 + "trace packet-dump",
30498 + "LDP debugging\n"
30499 + "Packet Dump\n")
30501 + ldp_traceflags |= LDP_TRACE_FLAG_PACKET_DUMP;
30502 + return CMD_SUCCESS;
30505 +DEFUN (ldp_trace_packet,
30506 + ldp_trace_packet_cmd,
30507 + "trace packet",
30508 + "LDP debugging\n"
30509 + "Packet tracing\n")
30511 + ldp_traceflags |= LDP_TRACE_FLAG_PACKET;
30512 + return CMD_SUCCESS;
30515 +DEFUN (ldp_trace_path,
30516 + ldp_trace_path_cmd,
30517 + "trace path",
30518 + "LDP debugging\n"
30519 + "PATH Info\n")
30521 + ldp_traceflags |= LDP_TRACE_FLAG_PATH;
30522 + return CMD_SUCCESS;
30525 +DEFUN (ldp_trace_periodic,
30526 + ldp_trace_periodic_cmd,
30527 + "trace periodic",
30528 + "LDP debugging\n"
30529 + "Periodic PDUs\n")
30531 + ldp_traceflags |= LDP_TRACE_FLAG_PERIODIC;
30532 + return CMD_SUCCESS;
30535 +DEFUN (ldp_trace_policy,
30536 + ldp_trace_policy_cmd,
30537 + "trace policy",
30538 + "LDP debugging\n"
30539 + "Policy tracing\n")
30541 + ldp_traceflags |= LDP_TRACE_FLAG_POLICY;
30542 + return CMD_SUCCESS;
30545 +DEFUN (ldp_trace_route,
30546 + ldp_trace_route_cmd,
30547 + "trace route",
30548 + "LDP debugging\n"
30549 + "Route Lookup tracing\n")
30551 + ldp_traceflags |= LDP_TRACE_FLAG_ROUTE;
30552 + return CMD_SUCCESS;
30555 +DEFUN (ldp_trace_state,
30556 + ldp_trace_state_cmd,
30557 + "trace state",
30558 + "LDP debugging\n"
30559 + "State transitions\n")
30561 + ldp_traceflags |= LDP_TRACE_FLAG_STATE;
30562 + return CMD_SUCCESS;
30565 +DEFUN (ldp_trace_task,
30566 + ldp_trace_task_cmd,
30567 + "trace task",
30568 + "LDP debugging\n"
30569 + "Task tracing\n")
30571 + ldp_traceflags |= LDP_TRACE_FLAG_TASK;
30572 + return CMD_SUCCESS;
30575 +DEFUN (ldp_trace_timer,
30576 + ldp_trace_timer_cmd,
30577 + "trace timer",
30578 + "LDP debugging\n"
30579 + "Timer tracing\n")
30581 + ldp_traceflags |= LDP_TRACE_FLAG_TIMER;
30582 + return CMD_SUCCESS;
30585 +DEFUN (ldp_trace_all,
30586 + ldp_trace_all_cmd,
30587 + "trace all",
30588 + "LDP debugging\n"
30589 + "All tracing\n")
30591 + ldp_traceflags |= LDP_TRACE_FLAG_ALL;
30592 + return CMD_SUCCESS;
30595 +DEFUN (ldp_trace_none,
30596 + ldp_trace_none_cmd,
30597 + "trace none",
30598 + "LDP debugging\n"
30599 + "Turn off all tracing\n")
30601 + ldp_traceflags = 0;
30602 + return CMD_SUCCESS;
30605 +/* address and egress changes should result in an event which goes through
30606 + all of the existing FECs/addresses and decides which to withdrawl and then
30607 + ask the system for which additional FECs/addresses should be sent */
30609 +DEFUN (ldp_address,
30610 + ldp_address_cmd,
30611 + "address-mode (lsr-id|ldp)",
30612 + "Addresses this LSR will announce\n"
30613 + "LSR-ID only\n"
30614 + "Only LDP interfaces\n")
30616 + struct ldp *ldp = (struct ldp*)vty->index;
30617 + if (!strncmp(argv[0], "lsr-id",6)) {
30618 + ldp->address = LDP_ADDRESS_LSRID;
30619 + } else if (!strncmp(argv[0], "ldp",3)) {
30620 + ldp->address = LDP_ADDRESS_LDP;
30621 + } else {
30622 + return CMD_WARNING;
30624 + return CMD_SUCCESS;
30627 +DEFUN (no_ldp_address,
30628 + no_ldp_address_cmd,
30629 + "no address-mode",
30630 + NO_STR
30631 + "Addresses this LSR will announce\n")
30633 + struct ldp *ldp = (struct ldp*)vty->index;
30634 + ldp->address = LDP_ADDRESS_ALL;
30635 + return CMD_SUCCESS;
30638 +DEFUN (ldp_egress,
30639 + ldp_egress_cmd,
30640 + "egress (lsr-id|connected)",
30641 + "Filter FECs this LSR will send mappings for\n"
30642 + "LSR-ID only\n"
30643 + "All connected subnets\n")
30645 + struct ldp *ldp = (struct ldp*)vty->index;
30646 + if (!strncmp(argv[0], "lsr-id",6)) {
30647 + ldp->egress = LDP_EGRESS_LSRID;
30648 + } else if (!strncmp(argv[0], "connected", 9)) {
30649 + ldp->egress = LDP_EGRESS_CONNECTED;
30650 + } else {
30651 + return CMD_WARNING;
30653 + return CMD_SUCCESS;
30656 +DEFUN (no_ldp_egress,
30657 + no_ldp_egress_cmd,
30658 + "no egress",
30659 + NO_STR
30660 + "Filter FECs this LSR will send mappings for\n")
30662 + struct ldp *ldp = (struct ldp*)vty->index;
30663 + ldp->egress = LDP_EGRESS_ALL;
30664 + return CMD_SUCCESS;
30667 +#if 0
30668 +DEFUN (ldp_egress_list,
30669 + ldp_egress_list_cmd,
30670 + "egress access-list (<1-199>|<1300-2699>|WORD)",
30671 + "Filter FECs this LSR will send mappings for\n"
30672 + "IP access-list number\n"
30673 + "IP access-list number (expanded range)\n"
30674 + "IP Access-list name\n")
30676 + return CMD_SUCCESS;
30679 +DEFUN (no_ldp_egress_list,
30680 + no_ldp_egress_list_cmd,
30681 + "no egress access-list (<1-199>|<1300-2699>|WORD)",
30682 + NO_STR
30683 + "Filter FECs this LSR will send mappings for\n"
30684 + "IP access-list number\n"
30685 + "IP access-list number (expanded range)\n"
30686 + "IP Access-list name\n")
30688 + return CMD_SUCCESS;
30690 +#endif
30692 +DEFUN (mpls_show_ldp_attr, mpls_show_ldp_attr_cmd,
30693 + "show ldp attr",
30694 + SHOW_STR
30695 + "LDP"
30696 + "ATTR\n")
30698 + struct ldp *ldp = ldp_get();
30700 + if (!ldp) {
30701 + vty_out (vty, "There isn't an active LDP instance.%s", VTY_NEWLINE);
30702 + return CMD_WARNING;
30704 + ldp_cfg_global_attr(ldp->h);
30705 + return CMD_SUCCESS;
30708 +DEFUN (mpls_show_ldp_fec, mpls_show_ldp_fec_cmd,
30709 + "show ldp fec",
30710 + SHOW_STR
30711 + "LDP"
30712 + "FEC\n")
30714 + struct ldp *ldp = ldp_get();
30715 + struct mpls_fec fec;
30716 + struct mpls_nexthop nh;
30717 + struct in_addr addr;
30719 + if (!ldp) {
30720 + vty_out (vty, "There isn't an active LDP instance.%s", VTY_NEWLINE);
30721 + return CMD_WARNING;
30724 + fec.index = 0;
30725 + while (ldp_cfg_fec_getnext(ldp->h, &fec, 0xFFFFFFFF) == MPLS_SUCCESS) {
30726 + addr.s_addr = htonl(fec.u.prefix.network.u.ipv4);
30727 + vty_out(vty, "FEC: %d %s/%d%s", fec.index, inet_ntoa(addr),
30728 + fec.u.prefix.length, VTY_NEWLINE);
30729 + nh.index = 0;
30730 + while (ldp_cfg_fec_nexthop_getnext(ldp->h, &fec, &nh,
30731 + 0xFFFFFFFF) == MPLS_SUCCESS) {
30732 + addr.s_addr = htonl(nh.ip.u.ipv4);
30733 + vty_out(vty, "\t%d %s %d%s", nh.index, inet_ntoa(addr),
30734 + nh.attached, VTY_NEWLINE);
30737 + return CMD_SUCCESS;
30740 +DEFUN (mpls_show_ldp_interface, mpls_show_ldp_interface_cmd,
30741 + "show ldp interface",
30742 + SHOW_STR
30743 + "LDP"
30744 + "interface\n")
30746 + struct ldp *ldp = ldp_get();
30747 + struct ldp_if iff;
30748 + struct ldp_addr addr;
30750 + if (!ldp) {
30751 + vty_out (vty, "There isn't an active LDP instance.%s", VTY_NEWLINE);
30752 + return CMD_WARNING;
30755 + iff.index = 0;
30756 + while (ldp_cfg_if_getnext(ldp->h, &iff, LDP_IF_CFG_BY_INDEX) ==
30757 + MPLS_SUCCESS) {
30758 + vty_out(vty, "INTF: %d%s", iff.index, VTY_NEWLINE);
30759 + addr.index = 0;
30760 + while (ldp_cfg_if_addr_getnext(ldp->h, &iff, &addr,
30761 + LDP_IF_ADDR_CFG_BY_INDEX | LDP_IF_CFG_BY_INDEX) == MPLS_SUCCESS) {
30762 + vty_out(vty, "\t%d%s", addr.index, VTY_NEWLINE);
30765 + return CMD_SUCCESS;
30768 +DEFUN (mpls_show_ldp_addr, mpls_show_ldp_addr_cmd,
30769 + "show ldp addr",
30770 + SHOW_STR
30771 + "LDP"
30772 + "addrs\n")
30774 + struct ldp *ldp = ldp_get();
30775 + struct ldp_addr addr;
30777 + if (!ldp) {
30778 + vty_out (vty, "There isn't an active LDP instance.%s", VTY_NEWLINE);
30779 + return CMD_WARNING;
30782 + memset(&addr, 0, sizeof(addr));
30783 + while (ldp_cfg_addr_getnext(ldp->h, &addr, 0) == MPLS_SUCCESS) {
30784 + vty_out(vty, "Addr: %d %08x%s", addr.index, addr.address.u.ipv4,
30785 + VTY_NEWLINE);
30786 + vty_out(vty, "\t%d%s", addr.session_index, VTY_NEWLINE);
30787 + vty_out(vty, "\t%d%s", addr.nexthop_index, VTY_NEWLINE);
30788 + vty_out(vty, "\t%d%s", addr.if_index, VTY_NEWLINE);
30790 + addr.session_index = 0;
30791 + addr.nexthop_index = 0;
30792 + addr.if_index = 0;
30794 + return CMD_SUCCESS;
30797 +DEFUN (mpls_show_ldp, mpls_show_ldp_cmd,
30798 + "show ldp",
30799 + SHOW_STR
30800 + "LDP global setting\n")
30802 + struct ldp *ldp = ldp_get();
30803 + struct in_addr lsr;
30804 + ldp_global g;
30806 + if (!ldp) {
30807 + vty_out (vty, "There isn't an active LDP instance.%s", VTY_NEWLINE);
30808 + return CMD_WARNING;
30811 + ldp_cfg_global_get(ldp->h,&g,0xFFFFFFFF);
30813 + lsr.s_addr = htonl(g.lsr_identifier.u.ipv4);
30814 + vty_out(vty, "LSR-ID: %-15s Admin State: %s%s", inet_ntoa(lsr),
30815 + admin_state[g.admin_state], VTY_NEWLINE);
30816 + lsr.s_addr = htonl(g.transport_address.u.ipv4);
30817 + vty_out(vty, "Transport Address: %-15s%s", inet_ntoa(lsr),
30818 + VTY_NEWLINE);
30819 + vty_out(vty, "Control Mode: %s\tRepair Mode: %s%s",
30820 + control_mode[g.lsp_control_mode], repair_mode[g.lsp_repair_mode],
30821 + VTY_NEWLINE);
30822 + vty_out(vty, "Propogate Release: %s\tLabel Merge: %s%s",
30823 + bool[g.propagate_release], bool[g.label_merge], VTY_NEWLINE);
30824 + vty_out(vty, "Retention Mode: %s\tLoop Detection Mode: %s%s",
30825 + retention_mode[g.label_retention_mode],
30826 + loop_detect_mode[g.loop_detection_mode], VTY_NEWLINE);
30827 + vty_out(vty, "TTL-less-domain: %s%s", bool[g.ttl_less_domain],
30828 + VTY_NEWLINE);
30829 + vty_out(vty, "Local TCP Port: %d\tLocal UDP Port: %d%s",
30830 + g.local_tcp_port, g.local_udp_port, VTY_NEWLINE);
30831 + vty_out(vty, "Keep-alive Time: %d\tKeep-alive Interval: %d%s",
30832 + g.keepalive_timer, g.keepalive_interval, VTY_NEWLINE);
30833 + vty_out(vty, "Hello Time: %d\tHello Interval: %d%s",
30834 + g.hellotime_timer, g.hellotime_interval, VTY_NEWLINE);
30836 + return CMD_SUCCESS;
30839 +void convert_seconds_to_string(uint32_t secs, char* buf) {
30840 + div_t mins;
30841 + div_t hours;
30842 + div_t days;
30843 + int h = 0;
30844 + int m = 0;
30845 + int s = 0;
30847 + if (secs >= 60) {
30848 + mins = div(secs, 60);
30849 + if (mins.quot >= 60) {
30850 + hours = div(mins.quot, 60);
30851 + if (hours.quot >= 24) {
30852 + days = div(hours.quot, 24);
30853 + h = days.rem;
30854 + m = hours.rem;
30855 + s = mins.rem;
30856 + sprintf(buf, "%dd %02d:%02d:%02d", days.quot, h, m, s);
30857 + return;
30858 + } else {
30859 + h = hours.quot;
30860 + m = hours.rem;
30861 + s = mins.rem;
30863 + } else {
30864 + h = 0;
30865 + m = mins.quot;
30866 + s = mins.rem;
30868 + } else {
30869 + h = 0;
30870 + m = 0;
30871 + s = secs;
30873 + sprintf(buf,"%02d:%02d:%02d", h, m, s);
30876 +DEFUN (mpls_show_ldp_neighbor, mpls_show_ldp_neighbor_cmd,
30877 + "show ldp neighbor",
30878 + SHOW_STR
30879 + "LDP related commands\n"
30880 + "Discovered neighbors\n"
30881 + "LDP identifier\n")
30883 + struct ldp *ldp = ldp_get();
30884 + ldp_adj adj;
30885 + ldp_addr addr;
30886 + ldp_entity e;
30887 + ldp_global g;
30888 + ldp_session s;
30889 + int count;
30890 + int addr_count;
30891 + uint32_t time_now;
30892 + char time_buf[13];
30893 + struct in_addr lsr;
30894 + struct in_addr src;
30895 + struct in_addr tr;
30896 + int label_space = 0;
30897 + ldp_if iff;
30898 + ldp_peer peer;
30900 +#if 0
30902 +Peer LDP Ident: 7.1.1.1:0; Local LDP Ident 8.1.1.1:0
30903 + TCP connection: 7.1.1.1.646 - 8.1.1.1.11006
30904 + State: Oper; Msgs sent/rcvd: 4/411; Downstream
30905 + Up time: 00:00:52
30906 + LDP discovery sources:
30907 + Ethernet1/0/0
30908 + Addresses bound to peer LDP Ident:
30909 + 2.0.0.29 7.1.1.1 59.0.0.199 212.10.1.1
30910 + 10.205.0.9
30912 +#endif
30914 + if (!ldp) {
30915 + vty_out (vty, "There isn't an active LDP instance.%s", VTY_NEWLINE);
30916 + return CMD_WARNING;
30919 + ldp_cfg_global_get(ldp->h,&g,0xFFFFFFFF);
30921 + count = 0;
30922 + adj.index = 0;
30923 + while (ldp_cfg_adj_getnext(ldp->h, &adj, 0xFFFFFFFF) ==
30924 + MPLS_SUCCESS) {
30925 + count++;
30927 + if (adj.entity_index) {
30928 + e.index = adj.entity_index;
30929 + ldp_cfg_entity_get(ldp->h,&e,0xFFFFFFFF);
30930 + if (e.entity_type == LDP_DIRECT) {
30931 + iff.index = e.sub_index;
30932 + ldp_cfg_if_get(ldp->h,&iff,0xFFFFFFFF);
30933 + label_space = iff.label_space;
30934 + } else {
30935 + peer.index = e.sub_index;
30936 + ldp_cfg_peer_get(ldp->h,&peer,0xFFFFFFFF);
30937 + label_space = peer.label_space;
30941 + lsr.s_addr = htonl(adj.remote_lsr_address.u.ipv4);
30942 + vty_out(vty, "Peer LDP Ident: %s:%d; Local LDP Ident: ", inet_ntoa(lsr),
30943 + adj.remote_label_space);
30944 + lsr.s_addr = htonl(g.lsr_identifier.u.ipv4);
30945 + vty_out(vty, "%s:%d%s", inet_ntoa(lsr), label_space, VTY_NEWLINE);
30947 + if (adj.session_index) {
30948 + s.index = adj.session_index;
30950 + if (ldp_cfg_session_get(ldp->h,&s,0xFFFFFFFF) != MPLS_SUCCESS) {
30951 + continue;
30954 + tr.s_addr = htonl(s.local_name.addr.u.ipv4);
30955 + vty_out(vty, "\tTCP connection: %s.%d", inet_ntoa(tr),
30956 + s.local_name.port);
30958 + src.s_addr = htonl(s.remote_name.addr.u.ipv4);
30959 + vty_out(vty, " - %s.%d%s", inet_ntoa(src), s.remote_name.port,
30960 + VTY_NEWLINE);
30962 + vty_out(vty, "\tState: %s; Msgs sent/recv: %d/%d; %s%s",
30963 + session_state[s.state], s.mesg_tx, s.mesg_rx,
30964 + distribution_mode[s.oper_distribution_mode], VTY_NEWLINE);
30965 + time_now = time(NULL);
30966 + convert_seconds_to_string(time_now - s.oper_up, time_buf);
30967 + vty_out(vty, "\tUp time: %s%s", time_buf, VTY_NEWLINE);
30969 + vty_out(vty, "\tLDP discovery sources:%s", VTY_NEWLINE);
30970 + } else {
30971 + vty_out(vty, "\tTCP connection: %s%s", "n/a", VTY_NEWLINE);
30972 + vty_out(vty, "\tState: discovery; Msgs sent/recv: -/-;%s",VTY_NEWLINE);
30973 + vty_out(vty, "\tUp time: %s%s", "-", VTY_NEWLINE);
30974 + vty_out(vty, "\tLDP discovery sources:%s", VTY_NEWLINE);
30976 + vty_out(vty, "\t ");
30978 + if (e.entity_type == LDP_DIRECT) {
30979 + vty_out(vty, "%s ", iff.handle->name);
30980 + } else {
30981 + vty_out(vty, "%s ", peer.peer_name);
30983 + vty_out(vty, "%s", VTY_NEWLINE);
30985 + if (adj.session_index) {
30986 + vty_out(vty, "\tAddresses bound to peer:%s", VTY_NEWLINE);
30988 + addr.index = 0;
30989 + addr_count = 0;
30990 + while (ldp_cfg_session_raddr_getnext(ldp->h, &s, &addr, 0xFFFFFFFF) ==
30991 + MPLS_SUCCESS) {
30992 + lsr.s_addr = htonl(addr.address.u.ipv4);
30993 + vty_out(vty, "\t");
30994 + if (!addr_count) {
30995 + vty_out(vty, " ");
30998 + vty_out(vty, "%s",inet_ntoa(lsr));
30999 + addr_count++;
31001 + if (addr_count == 4) {
31002 + vty_out(vty, "%s", VTY_NEWLINE);
31003 + addr_count = 0;
31006 + vty_out(vty, "%s", VTY_NEWLINE);
31009 + vty_out(vty, "%s", VTY_NEWLINE);
31010 + if (count == 0) {
31011 + vty_out(vty, "\tNo discovered neighbors%s", VTY_NEWLINE);
31013 + vty_out(vty, "%s", VTY_NEWLINE);
31015 + return CMD_SUCCESS;
31018 +DEFUN (mpls_show_ldp_session, mpls_show_ldp_session_cmd,
31019 + "show ldp session [A.B.C.D:E]",
31020 + SHOW_STR
31021 + "LDP related commands\n"
31022 + "Session information\n"
31023 + "LDP identifier\n")
31025 + struct ldp *ldp = ldp_get();
31026 + ldp_session session;
31027 + ldp_addr addr;
31028 + struct in_addr in;
31029 + int count = 0;
31031 + if (!ldp) {
31032 + vty_out (vty, "There isn't active LDP instance.%s", VTY_NEWLINE);
31033 + return CMD_WARNING;
31036 + session.index = 0;
31037 + while (ldp_cfg_session_getnext(ldp->h, &session, 0xFFFFFFFF) ==
31038 + MPLS_SUCCESS) {
31039 + count++;
31040 + in.s_addr = htonl(session.remote_dest.addr.u.ipv4);
31041 + vty_out(vty, "%-2d %s %-3d %s%s", session.index,
31042 + inet_ntoa(in), session.oper_keepalive,
31043 + session_state[session.state], VTY_NEWLINE);
31044 + addr.index = 0;
31045 + while (ldp_cfg_session_raddr_getnext(ldp->h, &session,
31046 + &addr, 0xFFFFFFFF) == MPLS_SUCCESS) {
31047 + in.s_addr = htonl(addr.address.u.ipv4);
31048 + vty_out(vty, "\t%s%s",inet_ntoa(in), VTY_NEWLINE);
31051 + if (count == 0) {
31052 + vty_out(vty, " no established sessions%s", VTY_NEWLINE);
31055 + return CMD_SUCCESS;
31058 +DEFUN (mpls_show_ldp_discovery, mpls_show_ldp_discovery_cmd,
31059 + "show ldp discovery",
31060 + SHOW_STR
31061 + "LDP related commands\n"
31062 + "Discovery information\n")
31064 + struct ldp *ldp = ldp_get();
31065 + struct ldp_interface *li;
31066 + ldp_if iff;
31067 + int count;
31068 + ldp_global g;
31069 + ldp_adj adj;
31070 + ldp_entity entity;
31071 + ldp_peer peer;
31072 + struct in_addr dst;
31073 + int first;
31075 + if (!ldp) {
31076 + vty_out (vty, "There isn't an active LDP instance.%s", VTY_NEWLINE);
31077 + return CMD_WARNING;
31080 + vty_out(vty, "%s", VTY_NEWLINE);
31082 + ldp_cfg_global_get(ldp->h,&g,0xFFFFFFFF);
31083 + dst.s_addr = htonl(g.lsr_identifier.u.ipv4);
31084 + vty_out(vty, "Local LSR Identifier: %s%s", inet_ntoa(dst), VTY_NEWLINE);
31085 + vty_out(vty, "%s", VTY_NEWLINE);
31086 + vty_out(vty, "Interface Discovery Sources:%s", VTY_NEWLINE);
31088 + count = 0;
31089 + iff.index = 0;
31090 + while (ldp_cfg_if_getnext(ldp->h, &iff, 0xFFFFFFFF) == MPLS_SUCCESS) {
31091 + li = iff.handle->info;
31092 + if (li->configured == MPLS_BOOL_FALSE) {
31093 + continue;
31095 + first = 1;
31096 + count++;
31097 + vty_out(vty, "\t%s: ", iff.handle->name);
31098 + if (iff.oper_state != MPLS_OPER_UP) {
31099 + vty_out(vty, "down");
31100 + } else {
31101 + vty_out(vty, "xmit");
31102 + entity.index = iff.entity_index;
31103 + if (ldp_cfg_entity_get(ldp->h, &entity, 0xFFFFFFFF) != MPLS_SUCCESS) {
31104 + continue;
31106 + do {
31107 + adj.index = entity.adj_index;
31108 + if (ldp_cfg_adj_get(ldp->h, &adj, 0xFFFFFFFF) == MPLS_SUCCESS) {
31109 + if (first) {
31110 + vty_out(vty, "/recv%s", VTY_NEWLINE);
31111 + first = 0;
31113 + dst.s_addr = htonl(adj.remote_lsr_address.u.ipv4);
31114 + vty_out(vty, "\t LDP Id: %s:%d%s ", inet_ntoa(dst),
31115 + adj.remote_label_space, VTY_NEWLINE);
31117 + } while (ldp_cfg_entity_adj_getnext(ldp->h, &entity) == MPLS_SUCCESS);
31119 + if (first) {
31120 + vty_out(vty, "%s", VTY_NEWLINE);
31123 + if (count == 0) {
31124 + vty_out(vty, "\tNo configured interfaces%s", VTY_NEWLINE);
31127 + vty_out(vty, "%s", VTY_NEWLINE);
31128 + vty_out(vty, "Targeted Discovery Sources:%s", VTY_NEWLINE);
31130 + count = 0;
31131 + peer.index = 0;
31132 + while (ldp_cfg_peer_getnext(ldp->h, &peer, 0xFFFFFFFF) ==
31133 + MPLS_SUCCESS) {
31134 + first = 1;
31135 + count++;
31136 + dst.s_addr = htonl(peer.dest.addr.u.ipv4);
31137 + vty_out(vty, "\t%s: xmit ", inet_ntoa(dst));
31138 + while (ldp_cfg_adj_getnext(ldp->h, &adj, 0xFFFFFFFF) == MPLS_SUCCESS) {
31139 + if (peer.entity_index == adj.entity_index) {
31140 + if (first) {
31141 + vty_out(vty, "/recv%s", VTY_NEWLINE);
31142 + first = 0;
31144 + dst.s_addr = htonl(adj.remote_lsr_address.u.ipv4);
31145 + vty_out(vty, "\t LDP Id: %s:%d%s ", inet_ntoa(dst),
31146 + adj.remote_label_space, VTY_NEWLINE);
31149 + if (first) {
31150 + vty_out(vty, "%s", VTY_NEWLINE);
31153 + if (count == 0) {
31154 + vty_out(vty, "\tNo configured peers%s", VTY_NEWLINE);
31156 + vty_out(vty, "%s", VTY_NEWLINE);
31158 + return CMD_SUCCESS;
31161 +void ldp_print_label(struct vty *vty, mpls_label_struct *l) {
31162 + switch(l->type) {
31163 + case MPLS_LABEL_TYPE_NONE:
31164 + vty_out(vty, "label: unknown");
31165 + break;
31166 + case MPLS_LABEL_TYPE_GENERIC:
31167 + vty_out(vty, "label: gen %d",l->u.gen);
31168 + break;
31169 + case MPLS_LABEL_TYPE_ATM:
31170 + vty_out(vty, "label: atm %d/%d",l->u.atm.vpi,l->u.atm.vci);
31171 + break;
31172 + case MPLS_LABEL_TYPE_FR:
31173 + vty_out(vty, "label: dlci %d",l->u.fr.dlci);
31174 + break;
31178 +DEFUN (mpls_show_ldp_database, mpls_show_ldp_database_cmd,
31179 + "show ldp database [A.B.C.D:E]",
31180 + SHOW_STR
31181 + "LDP related commands\n"
31182 + "Labeling information\n"
31183 + "LDP identifier\n")
31185 + struct ldp *ldp = ldp_get();
31186 + ldp_session session;
31187 + ldp_outlabel out;
31188 + ldp_inlabel in;
31189 + ldp_attr attr;
31190 + ldp_adj adj;
31191 + int count = 0;
31192 + struct in_addr fec;
31194 + if (!ldp) {
31195 + vty_out (vty, "There isn't an active LDP instance.%s", VTY_NEWLINE);
31196 + return CMD_WARNING;
31199 + attr.index = 0;
31200 + while (ldp_cfg_attr_getnext(ldp->h, &attr, 0xFFFFFFFF) == MPLS_SUCCESS) {
31201 + count++;
31203 + fec.s_addr = htonl(attr.fecTlv.fecElArray[0].addressEl.address);
31205 + vty_out(vty, " %s/%d ", inet_ntoa(fec),
31206 + attr.fecTlv.fecElArray[0].addressEl.preLen);
31208 + session.index = attr.session_index;
31209 + if (ldp_cfg_session_get(ldp->h, &session, 0xFFFFFFFF) != MPLS_SUCCESS) {
31210 + vty_out(vty, "no session%s",VTY_NEWLINE);
31211 + continue;
31214 + adj.index = session.adj_index;
31215 + if (ldp_cfg_adj_get(ldp->h, &adj, 0xFFFFFFFF) != MPLS_SUCCESS) {
31216 + vty_out(vty, "no adj%s",VTY_NEWLINE);
31217 + continue;
31220 + switch(attr.state) {
31221 + case LDP_LSP_STATE_MAP_RECV:
31222 + vty_out(vty, "remote binding: ");
31223 + out.index = attr.outlabel_index;
31224 + if (ldp_cfg_outlabel_get(ldp->h, &out, 0xFFFFFFFF) != MPLS_SUCCESS) {
31225 + vty_out(vty, "no outlabel");
31226 + } else {
31227 + ldp_print_label(vty,&out.info.label);
31229 + fec.s_addr = htonl(adj.remote_lsr_address.u.ipv4);
31230 + vty_out(vty, " lsr: %s:%d ", inet_ntoa(fec), adj.remote_label_space);
31231 + if (attr.ingress == MPLS_BOOL_TRUE) {
31232 + vty_out(vty, "ingress");
31234 + break;
31235 + case LDP_LSP_STATE_MAP_SENT:
31236 + in.index = attr.inlabel_index;
31237 + if (ldp_cfg_inlabel_get(ldp->h, &in, 0xFFFFFFFF) != MPLS_SUCCESS) {
31238 + vty_out(vty, "no inlabel%s", VTY_NEWLINE);
31239 + continue;
31241 + vty_out(vty, "local binding: ");
31242 + ldp_print_label(vty,&in.info.label);
31243 + break;
31244 + case LDP_LSP_STATE_WITH_SENT:
31245 + case LDP_LSP_STATE_WITH_RECV:
31246 + case LDP_LSP_STATE_NO_LABEL_RESOURCE_SENT:
31247 + case LDP_LSP_STATE_NO_LABEL_RESOURCE_RECV:
31248 + case LDP_LSP_STATE_ABORT_SENT:
31249 + case LDP_LSP_STATE_ABORT_RECV:
31250 + case LDP_LSP_STATE_NOTIF_SENT:
31251 + case LDP_LSP_STATE_NOTIF_RECV:
31252 + case LDP_LSP_STATE_REQ_RECV:
31253 + case LDP_LSP_STATE_REQ_SENT:
31254 + vty_out(vty, "%s:\t", attr_state[attr.state]);
31255 + fec.s_addr = htonl(adj.remote_lsr_address.u.ipv4);
31256 + vty_out(vty, "lsr: %s:%d", inet_ntoa(fec), adj.remote_label_space);
31257 + break;
31258 + default:
31259 + break;
31261 + vty_out(vty, "%s", VTY_NEWLINE);
31263 + if (count == 0) {
31264 + vty_out(vty, " no labeling info has been exchanged%s", VTY_NEWLINE);
31267 + return CMD_SUCCESS;
31270 +DEFUN(ldp_intf,
31271 + ldp_intf_cmd,
31272 + "mpls ip",
31273 + "MPLS interface configuration\n"
31274 + "Dynamic label distribution via LDP\n")
31276 + struct interface *ifp = vty->index;
31277 + struct ldp_interface *li;
31279 + MPLS_ASSERT(ifp->info);
31281 + li = ifp->info;
31283 + /*
31284 + * only configure ldp-portable the first time mpls ip is called
31285 + */
31286 + if (li->configured == MPLS_BOOL_FALSE) {
31287 + li->configured = MPLS_BOOL_TRUE;
31288 + li->admin_up = MPLS_BOOL_TRUE;
31290 + ldp_interface_create2(li);
31292 + vty->node = LDP_IF_NODE;
31294 + return CMD_SUCCESS;
31297 +DEFUN(no_ldp_intf,
31298 + no_ldp_intf_cmd,
31299 + "no mpls ip",
31300 + NO_STR
31301 + "MPLS interface configuration\n"
31302 + "remove LDP\n")
31304 + struct interface *ifp = vty->index;
31305 + struct ldp_interface *li;
31307 + MPLS_ASSERT(ifp->info);
31309 + li = ifp->info;
31310 + ldp_interface_delete2(li);
31312 + li->configured = MPLS_BOOL_FALSE;
31313 + li->admin_up = MPLS_BOOL_FALSE;
31315 + return CMD_SUCCESS;
31318 +DEFUN(ldp_xconnect_intf,
31319 + ldp_xconnect_intf_cmd,
31320 + "xconnect IPADDR VCID",
31321 + "Create a Layer 2 over MPLS Cross Connect\n"
31322 + "IP Address Remote Peer\n"
31323 + "VC-ID <0-255>\n")
31325 + struct interface *ifp = vty->index;
31326 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31327 + struct mpls_dest dest;
31328 + int vcid = 0;
31329 + int gid = -1;
31330 + struct ldp_remote_peer *rp;
31331 + struct ldp *ldp = ldp_get();
31333 +#if 0
31335 + if (!li->l2cc) {
31336 + /* user is trying to create a new L2CC interface */
31337 + li->l2cc = l2cc_if_new(li);
31339 +#endif
31341 + dest.addr.type = MPLS_FAMILY_IPV4;
31342 + VTY_GET_IPV4_ADDRESS("IPADDR",dest.addr.u.ipv4,argv[0]);
31343 + dest.addr.u.ipv4 = ntohl(dest.addr.u.ipv4);
31344 + dest.port = 646;
31346 + VTY_GET_UINT32_RANGE("VCID",vcid,argv[1],0,255);
31348 + if (ldp_remote_peer_find(ldp, &dest)) {
31349 + return CMD_WARNING;
31352 + rp = ldp_remote_peer_new(ldp);
31353 + listnode_add(ldp->peer_list, rp);
31354 + ldp_remote_peer_create(rp, &dest);
31356 +#if 0
31357 + l2cc_interface_create(li);
31358 +#endif
31360 + return CMD_SUCCESS;
31363 +DEFUN(no_ldp_xconnect_intf,
31364 + no_ldp_xconnect_intf_cmd,
31365 + "no xconnect IPADDR VCID",
31366 + NO_STR
31367 + "Delete a Layer 2 over MPLS Cross Connect\n"
31368 + "IP Address Remote Peer\n"
31369 + "VC-ID <0-255>\n")
31371 + struct interface *ifp = vty->index;
31372 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31373 + struct mpls_dest dest;
31374 + int vcid = 0;
31375 + int gid = -1;
31376 + struct ldp *ldp = ldp_get();
31377 + struct ldp_remote_peer *rp;
31379 + dest.addr.type = MPLS_FAMILY_IPV4;
31380 + VTY_GET_IPV4_ADDRESS("IPADDR",dest.addr.u.ipv4,argv[0]);
31381 + dest.port = 646;
31383 + VTY_GET_UINT32_RANGE("VCID",vcid,argv[1],0,255);
31385 + if ((rp = ldp_remote_peer_find(ldp,&dest))) {
31386 + listnode_delete(ldp->peer_list, rp);
31387 + ldp_remote_peer_delete(rp);
31388 + ldp_remote_peer_free(rp);
31391 +#if 0
31392 + if (li->l2cc) {
31393 + l2cc_interface_delete(li);
31394 + l2cc_if_free(li->l2cc);
31395 + li->l2cc = NULL;
31397 +#endif
31398 + return CMD_SUCCESS;
31401 +#if 0
31402 +DEFUN(ldp_xconnect_vfi_intf,
31403 + ldp_xconnect_vfi_intf_cmd,
31404 + "xconnect vfi WORD",
31405 + "Add interface to a VPLS\n"
31406 + "VFI Name\n")
31410 +DEFUN(no_ldp_xconnect_vfi_intf,
31411 + no_ldp_xconnect_vfi_intf_cmd,
31412 + "no xconnect vfi WORD",
31413 + NO_STR
31414 + "Remove interface from a VPLS\n"
31415 + "VFI Name\n")
31418 +#endif
31420 +DEFUN(ldp_if_distribution_mode,
31421 + ldp_if_distribution_mode_cmd,
31422 + "distribution-mode (dod|du)",
31423 + "MPLS interface configuration\n"
31424 + "distribution mode\n"
31425 + "Downstream on Demand or Downstream unsolicited\n")
31427 + struct interface *ifp = vty->index;
31428 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31429 + struct ldp *ldp = ldp_get();
31431 + if (!strncmp(argv[0],"dod",3)) {
31432 + li->entity.label_distribution_mode = LDP_DISTRIBUTION_ONDEMAND;
31433 + } else if (!strncmp(argv[0],"du",2)) {
31434 + li->entity.label_distribution_mode = LDP_DISTRIBUTION_UNSOLICITED;
31435 + } else {
31436 + return CMD_WARNING;
31439 + if (!ldp) {
31440 + li->create_on_hold = MPLS_BOOL_TRUE;
31441 + return CMD_SUCCESS;
31443 + ldp_interface_admin_state_start(li);
31444 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_DISTRIBUTION_MODE);
31445 + ldp_interface_admin_state_finish(li);
31446 + return CMD_SUCCESS;
31449 +DEFUN(no_ldp_if_distribution_mode,
31450 + no_ldp_if_distribution_mode_cmd,
31451 + "no distribution-mode",
31452 + NO_STR
31453 + "MPLS interface configuration\n"
31454 + "distribution mode\n")
31456 + struct interface *ifp = vty->index;
31457 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31458 + struct ldp *ldp = ldp_get();
31460 + li->entity.label_distribution_mode = LDP_ENTITY_DEF_DISTRIBUTION_MODE;
31461 + if (!ldp) {
31462 + li->create_on_hold = MPLS_BOOL_TRUE;
31463 + return CMD_SUCCESS;
31466 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_DISTRIBUTION_MODE);
31467 + return CMD_SUCCESS;
31470 +DEFUN(ldp_if_remote_tcp_port,
31471 + ldp_if_remote_tcp_port_cmd,
31472 + "remote-tcp-port <1-65535>",
31473 + "MPLS interface configuration\n"
31474 + "remote LDP port\n"
31475 + "port number\n")
31477 + struct interface *ifp = vty->index;
31478 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31479 + struct ldp *ldp = ldp_get();
31481 + li->entity.remote_tcp_port = atoi(argv[0]);
31482 + if (!ldp) {
31483 + li->create_on_hold = MPLS_BOOL_TRUE;
31484 + return CMD_SUCCESS;
31487 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_REMOTE_TCP);
31488 + return CMD_SUCCESS;
31491 +DEFUN(no_ldp_if_remote_tcp_port,
31492 + no_ldp_if_remote_tcp_port_cmd,
31493 + "no remote-tcp-port",
31494 + NO_STR
31495 + "MPLS interface configuration\n"
31496 + "remote LDP port\n")
31498 + struct interface *ifp = vty->index;
31499 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31500 + struct ldp *ldp = ldp_get();
31502 + li->entity.remote_tcp_port = LDP_ENTITY_DEF_REMOTE_TCP;
31503 + if (!ldp) {
31504 + li->create_on_hold = MPLS_BOOL_TRUE;
31505 + return CMD_SUCCESS;
31508 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_REMOTE_TCP);
31509 + return CMD_SUCCESS;
31512 +DEFUN(ldp_if_remote_udp_port,
31513 + ldp_if_remote_udp_port_cmd,
31514 + "remote-udp-port <1-65535>",
31515 + "MPLS interface configuration\n"
31516 + "remote LDP port\n"
31517 + "port number\n")
31519 + struct interface *ifp = vty->index;
31520 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31521 + struct ldp *ldp = ldp_get();
31523 + li->entity.remote_udp_port = atoi(argv[0]);
31524 + if (!ldp) {
31525 + li->create_on_hold = MPLS_BOOL_TRUE;
31526 + return CMD_SUCCESS;
31529 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_REMOTE_UDP);
31530 + return CMD_SUCCESS;
31533 +DEFUN(no_ldp_if_remote_udp_port,
31534 + no_ldp_if_remote_udp_port_cmd,
31535 + "no remote-udp-port",
31536 + NO_STR
31537 + "MPLS interface configuration\n"
31538 + "remote LDP port\n")
31540 + struct interface *ifp = vty->index;
31541 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31542 + struct ldp *ldp = ldp_get();
31544 + li->entity.remote_udp_port = LDP_ENTITY_DEF_REMOTE_UDP;
31545 + if (!ldp) {
31546 + li->create_on_hold = MPLS_BOOL_TRUE;
31547 + return CMD_SUCCESS;
31550 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_REMOTE_UDP);
31551 + return CMD_SUCCESS;
31554 +DEFUN(ldp_if_max_pdu,
31555 + ldp_if_max_pdu_cmd,
31556 + "max-pdu <64-9182>",
31557 + "MPLS interface configuration\n"
31558 + "maximum LDP PDU size\n"
31559 + "PDU size\n")
31561 + struct interface *ifp = vty->index;
31562 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31563 + struct ldp *ldp = ldp_get();
31565 + li->entity.max_pdu = atoi(argv[0]);
31566 + if (!ldp) {
31567 + li->create_on_hold = MPLS_BOOL_TRUE;
31568 + return CMD_SUCCESS;
31571 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_MAX_PDU);
31572 + return CMD_SUCCESS;
31575 +DEFUN(no_ldp_if_max_pdu,
31576 + no_ldp_if_max_pdu_cmd,
31577 + "no max-pdu",
31578 + NO_STR
31579 + "MPLS interface configuration\n"
31580 + "maximum LDP pdu size\n")
31582 + struct interface *ifp = vty->index;
31583 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31584 + struct ldp *ldp = ldp_get();
31586 + li->entity.max_pdu = LDP_ENTITY_DEF_MAX_PDU;
31587 + if (!ldp) {
31588 + li->create_on_hold = MPLS_BOOL_TRUE;
31589 + return CMD_SUCCESS;
31592 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_MAX_PDU);
31593 + return CMD_SUCCESS;
31596 +DEFUN(ldp_if_hello_interval,
31597 + ldp_if_hello_interval_cmd,
31598 + "hello-interval <1-60>",
31599 + "MPLS interface configuration\n"
31600 + "hello interval\n"
31601 + "interval in seconds\n")
31603 + struct interface *ifp = vty->index;
31604 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31605 + struct ldp *ldp = ldp_get();
31607 + li->entity.hellotime_interval = atoi(argv[0]);
31608 + if (!ldp) {
31609 + li->create_on_hold = MPLS_BOOL_TRUE;
31610 + return CMD_SUCCESS;
31613 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_HELLOTIME_INTERVAL);
31614 + return CMD_SUCCESS;
31617 +DEFUN(no_ldp_if_hello_interval,
31618 + no_ldp_if_hello_interval_cmd,
31619 + "no hello-interval",
31620 + NO_STR
31621 + "MPLS interface configuration\n"
31622 + "hello interval\n")
31624 + struct interface *ifp = vty->index;
31625 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31626 + struct ldp *ldp = ldp_get();
31628 + li->entity.hellotime_interval = LDP_ENTITY_DEF_HELLOTIME_INTERVAL;
31629 + if (!ldp) {
31630 + li->create_on_hold = MPLS_BOOL_TRUE;
31631 + return CMD_SUCCESS;
31634 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_HELLOTIME_INTERVAL);
31635 + return CMD_SUCCESS;
31638 +DEFUN(ldp_if_keepalive_interval,
31639 + ldp_if_keepalive_interval_cmd,
31640 + "keepalive-interval <1-60>",
31641 + "MPLS interface configuration\n"
31642 + "keepalive interval\n"
31643 + "interval in seconds\n")
31645 + struct interface *ifp = vty->index;
31646 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31647 + struct ldp *ldp = ldp_get();
31649 + li->entity.keepalive_interval = atoi(argv[0]);
31650 + if (!ldp) {
31651 + li->create_on_hold = MPLS_BOOL_TRUE;
31652 + return CMD_SUCCESS;
31655 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_KEEPALIVE_INTERVAL);
31656 + return CMD_SUCCESS;
31659 +DEFUN(no_ldp_if_keepalive_interval,
31660 + no_ldp_if_keepalive_interval_cmd,
31661 + "no keepalive-interval",
31662 + NO_STR
31663 + "MPLS interface configuration\n"
31664 + "keepalive interval\n")
31666 + struct interface *ifp = vty->index;
31667 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31668 + struct ldp *ldp = ldp_get();
31670 + li->entity.keepalive_interval = LDP_ENTITY_DEF_KEEPALIVE_INTERVAL;
31671 + if (!ldp) {
31672 + li->create_on_hold = MPLS_BOOL_TRUE;
31673 + return CMD_SUCCESS;
31676 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_KEEPALIVE_INTERVAL);
31677 + return CMD_SUCCESS;
31680 +DEFUN(ldp_if_max_session_attempt,
31681 + ldp_if_max_session_attempt_cmd,
31682 + "max-session-attempt <0-1024>",
31683 + "MPLS interface configuration\n"
31684 + "maximum LDP session setup attempt\n"
31685 + "Number of attempts (0 means keep trying)\n")
31687 + struct interface *ifp = vty->index;
31688 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31689 + struct ldp *ldp = ldp_get();
31691 + li->entity.session_setup_count = atoi(argv[0]);
31692 + if (!ldp) {
31693 + li->create_on_hold = MPLS_BOOL_TRUE;
31694 + return CMD_SUCCESS;
31697 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_SESSION_SETUP_COUNT);
31698 + return CMD_SUCCESS;
31701 +DEFUN(no_ldp_if_max_session_attempt,
31702 + no_ldp_if_max_session_attempt_cmd,
31703 + "no max-session-attempt\n",
31704 + NO_STR
31705 + "MPLS interface configuration\n"
31706 + "maximum LDP session setup attempt\n")
31708 + struct interface *ifp = vty->index;
31709 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31710 + struct ldp *ldp = ldp_get();
31712 + li->entity.session_setup_count = LDP_ENTITY_DEF_SESSIONSETUP_COUNT;
31713 + if (!ldp) {
31714 + li->create_on_hold = MPLS_BOOL_TRUE;
31715 + return CMD_SUCCESS;
31718 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_SESSION_SETUP_COUNT);
31719 + return CMD_SUCCESS;
31722 +DEFUN(ldp_if_max_path_vector,
31723 + ldp_if_max_path_vector_cmd,
31724 + "max-path-vector <1-255>",
31725 + "MPLS interface configuration\n"
31726 + "maximum path vector\n"
31727 + "number of entries\n")
31729 + struct interface *ifp = vty->index;
31730 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31731 + struct ldp *ldp = ldp_get();
31733 + li->entity.path_vector_limit = atoi(argv[0]);
31734 + if (!ldp) {
31735 + li->create_on_hold = MPLS_BOOL_TRUE;
31736 + return CMD_SUCCESS;
31739 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_PATHVECTOR_LIMIT);
31740 + return CMD_SUCCESS;
31743 +DEFUN(no_ldp_if_max_path_vector,
31744 + no_ldp_if_max_path_vector_cmd,
31745 + "no max-path-vector",
31746 + NO_STR
31747 + "MPLS interface configuration\n"
31748 + "maximum path vector\n")
31750 + struct interface *ifp = vty->index;
31751 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31752 + struct ldp *ldp = ldp_get();
31754 + li->entity.path_vector_limit = LDP_ENTITY_DEF_PATHVECTOR_LIMIT;
31755 + if (!ldp) {
31756 + li->create_on_hold = MPLS_BOOL_TRUE;
31757 + return CMD_SUCCESS;
31760 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_PATHVECTOR_LIMIT);
31761 + return CMD_SUCCESS;
31764 +DEFUN(ldp_if_max_hop_count,
31765 + ldp_if_max_hop_count_cmd,
31766 + "max-hop-count <1-1024>",
31767 + "MPLS interface configuration\n"
31768 + "maximum hop count\n"
31769 + "number of hops\n")
31771 + struct interface *ifp = vty->index;
31772 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31773 + struct ldp *ldp = ldp_get();
31775 + li->entity.hop_count_limit = atoi(argv[0]);
31776 + if (!ldp) {
31777 + li->create_on_hold = MPLS_BOOL_TRUE;
31778 + return CMD_SUCCESS;
31781 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_HOPCOUNT_LIMIT);
31782 + return CMD_SUCCESS;
31785 +DEFUN(no_ldp_if_max_hop_count,
31786 + no_ldp_if_max_hop_count_cmd,
31787 + "no max-hop-count",
31788 + NO_STR
31789 + "MPLS interface configuration\n"
31790 + "maximum hop count\n")
31792 + struct interface *ifp = vty->index;
31793 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31794 + struct ldp *ldp = ldp_get();
31796 + li->entity.hop_count_limit = LDP_ENTITY_DEF_HOPCOUNT_LIMIT;
31797 + if (!ldp) {
31798 + li->create_on_hold = MPLS_BOOL_TRUE;
31799 + return CMD_SUCCESS;
31802 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_HOPCOUNT_LIMIT);
31803 + return CMD_SUCCESS;
31806 +DEFUN(ldp_if_max_label_requests,
31807 + ldp_if_max_label_requests_cmd,
31808 + "max-label-requests <0-1024>",
31809 + "MPLS interface configuration\n"
31810 + "maximum times to make a request for a FEC\n"
31811 + "Number of attempts (0 means keep trying)\n")
31813 + struct interface *ifp = vty->index;
31814 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31815 + struct ldp *ldp = ldp_get();
31817 + li->entity.label_request_count = atoi(argv[0]);
31818 + if (!ldp) {
31819 + li->create_on_hold = MPLS_BOOL_TRUE;
31820 + return CMD_SUCCESS;
31823 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_REQUEST_COUNT);
31824 + return CMD_SUCCESS;
31827 +DEFUN(no_ldp_if_max_label_requests,
31828 + no_ldp_if_max_label_requests_cmd,
31829 + "no max-label-requests",
31830 + NO_STR
31831 + "MPLS interface configuration\n"
31832 + "maximum times to make a request for a FEC\n")
31834 + struct interface *ifp = vty->index;
31835 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31836 + struct ldp *ldp = ldp_get();
31838 + li->entity.label_request_count = LDP_ENTITY_DEF_REQUEST_COUNT;
31839 + if (!ldp) {
31840 + li->create_on_hold = MPLS_BOOL_TRUE;
31841 + return CMD_SUCCESS;
31844 + ldp_cfg_entity_set(ldp->h, &li->entity, LDP_ENTITY_CFG_REQUEST_COUNT);
31845 + return CMD_SUCCESS;
31848 +DEFUN(ldp_if_ttl_less_domain,
31849 + ldp_if_ttl_less_domain_cmd,
31850 + "ttl-less-domain",
31851 + "MPLS interface configuration\n"
31852 + "TTL less domain\n")
31854 + struct interface *ifp = vty->index;
31855 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31856 + struct ldp *ldp = ldp_get();
31858 + li->entity.remote_in_ttl_less_domain = MPLS_BOOL_TRUE;
31859 + if (!ldp) {
31860 + li->create_on_hold = MPLS_BOOL_TRUE;
31861 + return CMD_SUCCESS;
31864 + return CMD_SUCCESS;
31867 +DEFUN(no_ldp_if_ttl_less_domain,
31868 + no_ldp_if_ttl_less_domain_cmd,
31869 + "no ttl-less-domain",
31870 + NO_STR
31871 + "MPLS interface configuration\n"
31872 + "TTL less domain\n")
31874 + struct interface *ifp = vty->index;
31875 + struct ldp_interface *li = (struct ldp_interface*)ifp->info;
31876 + struct ldp *ldp = ldp_get();
31878 + li->entity.remote_in_ttl_less_domain = MPLS_BOOL_FALSE;
31879 + if (!ldp) {
31880 + return CMD_SUCCESS;
31883 + return CMD_SUCCESS;
31886 +static int ldp_if_config_write (struct vty *vty) {
31887 + return 0;
31890 +static int ldp_config_write (struct vty *vty) {
31891 + struct ldp *ldp = ldp_get();
31892 + ldp_global g;
31893 + int write = 0;
31894 + struct in_addr addr;
31896 + if (ldp) {
31897 + vty_out (vty, "!%s", VTY_NEWLINE);
31898 + vty_out (vty, "mpls ldp%s", VTY_NEWLINE);
31899 + write++;
31901 + if (ldp_traceflags & LDP_TRACE_FLAG_ADDRESS)
31902 + vty_out (vty, " trace address%s", VTY_NEWLINE);
31903 + if (ldp_traceflags & LDP_TRACE_FLAG_BINDING)
31904 + vty_out (vty, " trace binding%s", VTY_NEWLINE);
31905 + if (ldp_traceflags & LDP_TRACE_FLAG_DEBUG)
31906 + vty_out (vty, " trace debug%s", VTY_NEWLINE);
31907 + if (ldp_traceflags & LDP_TRACE_FLAG_ERROR)
31908 + vty_out (vty, " trace error%s", VTY_NEWLINE);
31909 + if (ldp_traceflags & LDP_TRACE_FLAG_EVENT)
31910 + vty_out (vty, " trace event%s", VTY_NEWLINE);
31911 + if (ldp_traceflags & LDP_TRACE_FLAG_GENERAL)
31912 + vty_out (vty, " trace general%s", VTY_NEWLINE);
31913 + if (ldp_traceflags & LDP_TRACE_FLAG_INIT)
31914 + vty_out (vty, " trace init%s", VTY_NEWLINE);
31915 + if (ldp_traceflags & LDP_TRACE_FLAG_LABEL)
31916 + vty_out (vty, " trace label%s", VTY_NEWLINE);
31917 + if (ldp_traceflags & LDP_TRACE_FLAG_NORMAL)
31918 + vty_out (vty, " trace normal%s", VTY_NEWLINE);
31919 + if (ldp_traceflags & LDP_TRACE_FLAG_NOTIF)
31920 + vty_out (vty, " trace notification%s", VTY_NEWLINE);
31921 + if (ldp_traceflags & LDP_TRACE_FLAG_PACKET_DUMP)
31922 + vty_out (vty, " trace packet-dump%s", VTY_NEWLINE);
31923 + if (ldp_traceflags & LDP_TRACE_FLAG_PACKET)
31924 + vty_out (vty, " trace packet%s", VTY_NEWLINE);
31925 + if (ldp_traceflags & LDP_TRACE_FLAG_PATH)
31926 + vty_out (vty, " trace path%s", VTY_NEWLINE);
31927 + if (ldp_traceflags & LDP_TRACE_FLAG_PERIODIC)
31928 + vty_out (vty, " trace periodic%s", VTY_NEWLINE);
31929 + if (ldp_traceflags & LDP_TRACE_FLAG_POLICY)
31930 + vty_out (vty, " trace policy%s", VTY_NEWLINE);
31931 + if (ldp_traceflags & LDP_TRACE_FLAG_ROUTE)
31932 + vty_out (vty, " trace route%s", VTY_NEWLINE);
31933 + if (ldp_traceflags & LDP_TRACE_FLAG_STATE)
31934 + vty_out (vty, " trace state%s", VTY_NEWLINE);
31935 + if (ldp_traceflags & LDP_TRACE_FLAG_TASK)
31936 + vty_out (vty, " trace task%s", VTY_NEWLINE);
31937 + if (ldp_traceflags & LDP_TRACE_FLAG_TIMER)
31938 + vty_out (vty, " trace timer%s", VTY_NEWLINE);
31940 + ldp_cfg_global_get(ldp->h,&g, 0xFFFFFFFF);
31942 + if (g.lsp_control_mode != LDP_GLOBAL_DEF_CONTROL_MODE) {
31943 + vty_out (vty, " lsp-control-mode ");
31944 + if (g.lsp_control_mode == LDP_CONTROL_INDEPENDENT) {
31945 + vty_out (vty, "independent%s", VTY_NEWLINE);
31946 + } else {
31947 + vty_out (vty, "ordered%s", VTY_NEWLINE);
31950 + if (g.label_retention_mode != LDP_GLOBAL_DEF_RETENTION_MODE) {
31951 + vty_out (vty, " label-retention-mode ");
31952 + if (g.label_retention_mode == LDP_RETENTION_LIBERAL) {
31953 + vty_out (vty, "liberal%s", VTY_NEWLINE);
31954 + } else {
31955 + vty_out (vty, "conservative%s", VTY_NEWLINE);
31958 + if (g.lsp_repair_mode != LDP_GLOBAL_DEF_REPAIR_MODE) {
31959 + vty_out (vty, " lsp-repair-mode ");
31960 + if (g.lsp_repair_mode == LDP_REPAIR_LOCAL) {
31961 + vty_out (vty, "local%s", VTY_NEWLINE);
31962 + } else {
31963 + vty_out (vty, "global%s", VTY_NEWLINE);
31966 + if (g.propagate_release != LDP_GLOBAL_DEF_PROPOGATE_RELEASE) {
31967 + if (g.propagate_release == MPLS_BOOL_TRUE) {
31968 + vty_out (vty, " propagate-release%s", VTY_NEWLINE);
31969 + } else {
31970 + vty_out (vty, " no propagate-release%s", VTY_NEWLINE);
31973 + if (g.label_merge != LDP_GLOBAL_DEF_LABEL_MERGE) {
31974 + if (g.label_merge == MPLS_BOOL_TRUE) {
31975 + vty_out (vty, " label-merge%s", VTY_NEWLINE);
31976 + } else {
31977 + vty_out (vty, " no label-merge%s", VTY_NEWLINE);
31980 + if (g.loop_detection_mode != LDP_GLOBAL_DEF_LOOP_DETECTION_MODE) {
31981 + if (g.loop_detection_mode == LDP_LOOP_HOPCOUNT) {
31982 + vty_out (vty, " loop-detection-mode hop%s", VTY_NEWLINE);
31983 + } else if (g.loop_detection_mode == LDP_LOOP_PATHVECTOR) {
31984 + vty_out (vty, " loop-detection-mode path%s", VTY_NEWLINE);
31985 + } else if (g.loop_detection_mode == LDP_LOOP_HOPCOUNT_PATHVECTOR) {
31986 + vty_out (vty, " loop-detection-mode both%s", VTY_NEWLINE);
31987 + } else {
31988 + vty_out (vty, " no loop-detection-mode%s", VTY_NEWLINE);
31991 + if (g.ttl_less_domain != MPLS_BOOL_FALSE) {
31992 + vty_out (vty, " ttl-less-domain%s", VTY_NEWLINE);
31994 + if (g.local_tcp_port != LDP_GLOBAL_DEF_LOCAL_TCP_PORT) {
31995 + vty_out (vty, " local-tcp-port %d%s", g.local_tcp_port, VTY_NEWLINE);
31997 + if (g.local_udp_port != LDP_GLOBAL_DEF_LOCAL_UDP_PORT) {
31998 + vty_out (vty, " local-udp-port %d%s", g.local_udp_port, VTY_NEWLINE);
32001 + switch (ldp->egress) {
32002 + case LDP_EGRESS_LSRID:
32003 + vty_out (vty, " egress lsr-id%s", VTY_NEWLINE);
32004 + break;
32005 + case LDP_EGRESS_CONNECTED:
32006 + vty_out (vty, " egress connected%s", VTY_NEWLINE);
32007 + break;
32008 + default:
32009 + break;
32012 + switch (ldp->address) {
32013 + case LDP_ADDRESS_LSRID:
32014 + vty_out (vty, " address-mode lsr-id%s", VTY_NEWLINE);
32015 + break;
32016 + case LDP_ADDRESS_LDP:
32017 + vty_out (vty, " address-mode ldp%s", VTY_NEWLINE);
32018 + break;
32019 + default:
32020 + break;
32023 + switch (ldp->trans_addr) {
32024 + case LDP_TRANS_ADDR_LSRID:
32025 + vty_out (vty, " transport-address lsr-id%s", VTY_NEWLINE);
32026 + break;
32027 + case LDP_TRANS_ADDR_INTERFACE:
32028 + vty_out (vty, " transport-address interface%s", VTY_NEWLINE);
32029 + break;
32030 + case LDP_TRANS_ADDR_STATIC_IP:
32031 + addr.s_addr = htonl(g.transport_address.u.ipv4);
32032 + vty_out (vty, " transport-address %s%s", inet_ntoa(addr), VTY_NEWLINE);
32033 + break;
32034 + case LDP_TRANS_ADDR_STATIC_INTERFACE:
32035 + vty_out (vty, " transport-address %s%s", ldp->trans_addr_ifname,
32036 + VTY_NEWLINE);
32037 + break;
32038 + default:
32039 + break;
32042 + return write;
32045 +#if 0
32046 +int ldp_interface_config_write(struct vty *vty) {
32047 + struct ldp *ldp = ldp_get();
32048 + struct listnode* node;
32049 + struct interface *ifp;
32051 + ldp_entity e;
32052 + mpls_fec l;
32053 + int write = 0;
32055 + if (li && li->ldp) {
32056 + } else if (li && li->l2cc) {
32057 +// struct in_addr tmp;
32058 + l2 = li->l2cc;
32059 + ldp = ldp_get();
32061 + write++;
32063 + if (l2->l2cc.index) {
32064 + l.index = l2->l2cc.index;
32065 + ldp_cfg_fec_get(ldp->h, &l, 0xFFFFFFFF);
32066 + } else {
32067 + memcpy(&l,&l2->l2cc,sizeof(ldp_fec));
32069 +#if 0
32070 + tmp.s_addr = htonl(l.info.nh.ip.u.ipv4);
32071 + vty_out(vty, " mpls l2cc peer %s",inet_ntoa(tmp));
32072 + vty_out(vty, " vcid %d",l.info.u.l2cc.connection_id);
32073 + if (l.info.u.l2cc.group_id) {
32074 + vty_out(vty, " groupid %d", l.info.u.l2cc.group_id);
32076 +#endif
32077 + vty_out(vty, "%s", VTY_NEWLINE);
32079 + vty_out(vty, " !%s",VTY_NEWLINE);
32083 + return write;
32085 +#endif
32087 +void ldp_vty_show_init() {
32089 + install_element (VIEW_NODE, &mpls_show_ldp_cmd);
32090 + install_element (ENABLE_NODE, &mpls_show_ldp_cmd);
32092 + install_element (VIEW_NODE, &mpls_show_ldp_fec_cmd);
32093 + install_element (ENABLE_NODE, &mpls_show_ldp_fec_cmd);
32095 + install_element (VIEW_NODE, &mpls_show_ldp_attr_cmd);
32096 + install_element (ENABLE_NODE, &mpls_show_ldp_attr_cmd);
32098 + install_element (VIEW_NODE, &mpls_show_ldp_addr_cmd);
32099 + install_element (ENABLE_NODE, &mpls_show_ldp_addr_cmd);
32101 + install_element (VIEW_NODE, &mpls_show_ldp_interface_cmd);
32102 + install_element (ENABLE_NODE, &mpls_show_ldp_interface_cmd);
32104 + install_element (VIEW_NODE, &mpls_show_ldp_neighbor_cmd);
32105 + install_element (ENABLE_NODE, &mpls_show_ldp_neighbor_cmd);
32107 + install_element (VIEW_NODE, &mpls_show_ldp_session_cmd);
32108 + install_element (ENABLE_NODE, &mpls_show_ldp_session_cmd);
32110 + install_element (VIEW_NODE, &mpls_show_ldp_discovery_cmd);
32111 + install_element (ENABLE_NODE, &mpls_show_ldp_discovery_cmd);
32113 + install_element (VIEW_NODE, &mpls_show_ldp_database_cmd);
32114 + install_element (ENABLE_NODE, &mpls_show_ldp_database_cmd);
32117 +extern void dump_mpls_node(struct vty*,struct route_node*);
32119 +static int ldp_interface_config_write(struct vty *vty) {
32120 + struct ldp *ldp = ldp_get();
32121 + struct listnode* node;
32122 + struct interface *ifp;
32123 + struct ldp_interface *li;
32124 + ldp_entity e;
32126 + for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) {
32128 + vty_out(vty, "interface %s%s", ifp->name, VTY_NEWLINE);
32130 + if (ifp->desc) {
32131 + vty_out(vty, " description %s%s", ifp->desc, VTY_NEWLINE);
32134 + li = ifp->info;
32135 + if (li) {
32136 + if (li->configured == MPLS_BOOL_TRUE) {
32137 + vty_out(vty, " mpls ip%s", VTY_NEWLINE);
32140 + if (li->entity.index && ldp) {
32141 + e.index = li->entity.index;
32142 + ldp_cfg_entity_get(ldp->h, &e, 0xFFFFFFFF);
32143 + } else {
32144 + memcpy(&e,&li->entity,sizeof(ldp_entity));
32147 + if (e.label_distribution_mode != LDP_ENTITY_DEF_DISTRIBUTION_MODE) {
32148 + vty_out(vty, " distribution-mode ");
32149 + if (e.label_distribution_mode == LDP_DISTRIBUTION_ONDEMAND) {
32150 + vty_out(vty, "dod%s", VTY_NEWLINE);
32151 + } else {
32152 + vty_out(vty, "du%s", VTY_NEWLINE);
32155 + if (e.remote_tcp_port != LDP_ENTITY_DEF_REMOTE_TCP) {
32156 + vty_out(vty, " remote-tcp-port %d%s", e.remote_tcp_port,
32157 + VTY_NEWLINE);
32159 + if (e.remote_udp_port != LDP_ENTITY_DEF_REMOTE_UDP) {
32160 + vty_out(vty, " remote-udp-port %d%s", e.remote_udp_port,
32161 + VTY_NEWLINE);
32163 + if (e.max_pdu != LDP_ENTITY_DEF_MAX_PDU) {
32164 + vty_out(vty, " max-pdu %d%s", e.max_pdu, VTY_NEWLINE);
32166 + if (e.hellotime_interval != LDP_ENTITY_DEF_HELLOTIME_INTERVAL) {
32167 + vty_out(vty, " hello-interval %d%s", e.hellotime_interval,
32168 + VTY_NEWLINE);
32170 + if (e.keepalive_interval != LDP_ENTITY_DEF_KEEPALIVE_INTERVAL) {
32171 + vty_out(vty, " keepalive-interval %d%s",
32172 + e.keepalive_interval, VTY_NEWLINE);
32174 + if (e.session_setup_count != LDP_ENTITY_DEF_SESSIONSETUP_COUNT) {
32175 + vty_out(vty, " max-session-attempt %d%s",
32176 + e.session_setup_count, VTY_NEWLINE);
32178 + if (e.path_vector_limit != LDP_ENTITY_DEF_PATHVECTOR_LIMIT) {
32179 + vty_out(vty, " max-path-vector %d%s",
32180 + e.path_vector_limit, VTY_NEWLINE);
32182 + if (e.hop_count_limit != LDP_ENTITY_DEF_HOPCOUNT_LIMIT) {
32183 + vty_out(vty, " max-hop-count %d%s",
32184 + e.hop_count_limit, VTY_NEWLINE);
32186 + if (e.label_request_count != LDP_ENTITY_DEF_REQUEST_COUNT) {
32187 + vty_out(vty, " max-label-requests %d%s",
32188 + e.label_request_count, VTY_NEWLINE);
32191 + vty_out(vty, "!%s", VTY_NEWLINE);
32193 + return 0;
32196 +static struct cmd_node ldp_node = {LDP_NODE,"%s(config-ldp)# ",1};
32197 +static struct cmd_node interface_node = {INTERFACE_NODE,"%s(config-if)# ",1};
32198 +static struct cmd_node ldp_if_node = {LDP_IF_NODE,"%s(config-if-ldp)# ",1};
32200 +void ldp_vty_init () {
32202 + install_node (&ldp_node, ldp_config_write);
32204 + install_default (LDP_NODE);
32206 + install_element (CONFIG_NODE, &mpls_ldp_cmd);
32207 + install_element (CONFIG_NODE, &no_mpls_ldp_cmd);
32209 + install_element (LDP_NODE, &ldp_lsrid_cmd);
32210 + install_element (LDP_NODE, &no_ldp_lsrid_cmd);
32212 + install_element (LDP_NODE, &ldp_disable_cmd);
32213 + install_element (LDP_NODE, &no_ldp_disable_cmd);
32215 + install_element (LDP_NODE, &ldp_transport_address_cmd);
32216 + install_element (LDP_NODE, &no_ldp_transport_address_cmd);
32218 + install_element (LDP_NODE, &ldp_lsp_control_mode_cmd);
32219 + install_element (LDP_NODE, &no_ldp_lsp_control_mode_cmd);
32221 + install_element (LDP_NODE, &ldp_label_retention_mode_cmd);
32222 + install_element (LDP_NODE, &no_ldp_label_retention_mode_cmd);
32224 + install_element (LDP_NODE, &ldp_lsp_repair_mode_cmd);
32225 + install_element (LDP_NODE, &no_ldp_lsp_repair_mode_cmd);
32227 + install_element (LDP_NODE, &ldp_propogate_release_cmd);
32228 + install_element (LDP_NODE, &no_ldp_propogate_release_cmd);
32230 + install_element (LDP_NODE, &ldp_label_merge_cmd);
32231 + install_element (LDP_NODE, &no_ldp_label_merge_cmd);
32233 + install_element (LDP_NODE, &ldp_global_loop_detection_mode_cmd);
32234 + install_element (LDP_NODE, &no_ldp_loop_detection_mode_cmd);
32236 + install_element (LDP_NODE, &ldp_ttl_less_domain_cmd);
32237 + install_element (LDP_NODE, &no_ldp_ttl_less_domain_cmd);
32239 + install_element (LDP_NODE, &ldp_local_tcp_port_cmd);
32240 + install_element (LDP_NODE, &no_ldp_local_tcp_port_cmd);
32242 + install_element (LDP_NODE, &ldp_local_udp_port_cmd);
32243 + install_element (LDP_NODE, &no_ldp_local_udp_port_cmd);
32245 + install_element (LDP_NODE, &ldp_trace_address_cmd);
32246 + install_element (LDP_NODE, &ldp_trace_binding_cmd);
32247 + install_element (LDP_NODE, &ldp_trace_debug_cmd);
32248 + install_element (LDP_NODE, &ldp_trace_error_cmd);
32249 + install_element (LDP_NODE, &ldp_trace_event_cmd);
32250 + install_element (LDP_NODE, &ldp_trace_general_cmd);
32251 + install_element (LDP_NODE, &ldp_trace_init_cmd);
32252 + install_element (LDP_NODE, &ldp_trace_label_cmd);
32253 + install_element (LDP_NODE, &ldp_trace_normal_cmd);
32254 + install_element (LDP_NODE, &ldp_trace_notif_cmd);
32255 + install_element (LDP_NODE, &ldp_trace_packet_dump_cmd);
32256 + install_element (LDP_NODE, &ldp_trace_packet_cmd);
32257 + install_element (LDP_NODE, &ldp_trace_path_cmd);
32258 + install_element (LDP_NODE, &ldp_trace_periodic_cmd);
32259 + install_element (LDP_NODE, &ldp_trace_policy_cmd);
32260 + install_element (LDP_NODE, &ldp_trace_route_cmd);
32261 + install_element (LDP_NODE, &ldp_trace_state_cmd);
32262 + install_element (LDP_NODE, &ldp_trace_task_cmd);
32263 + install_element (LDP_NODE, &ldp_trace_timer_cmd);
32264 + install_element (LDP_NODE, &ldp_trace_all_cmd);
32265 + install_element (LDP_NODE, &ldp_trace_none_cmd);
32267 + install_element (LDP_NODE, &ldp_egress_cmd);
32268 + install_element (LDP_NODE, &no_ldp_egress_cmd);
32269 + install_element (LDP_NODE, &ldp_address_cmd);
32270 + install_element (LDP_NODE, &no_ldp_address_cmd);
32272 + install_node(&interface_node, ldp_interface_config_write);
32274 + install_element(CONFIG_NODE, &interface_cmd);
32275 + install_default(INTERFACE_NODE);
32277 + install_element(INTERFACE_NODE,&interface_desc_cmd);
32278 + install_element(INTERFACE_NODE,&no_interface_desc_cmd);
32280 + install_node (&ldp_if_node, ldp_if_config_write);
32281 + install_default (LDP_IF_NODE);
32283 + install_element (INTERFACE_NODE, &ldp_intf_cmd);
32284 + install_element (INTERFACE_NODE, &no_ldp_intf_cmd);
32286 +#if 0
32287 + install_element (INTERFACE_NODE, &ldp_xconnect_intf_cmd);
32288 + install_element (INTERFACE_NODE, &no_ldp_xconnect_intf_cmd);
32289 +#endif
32291 + install_element (LDP_IF_NODE, &ldp_if_remote_tcp_port_cmd);
32292 + install_element (LDP_IF_NODE, &no_ldp_if_remote_tcp_port_cmd);
32294 + install_element (LDP_IF_NODE, &ldp_if_remote_udp_port_cmd);
32295 + install_element (LDP_IF_NODE, &no_ldp_if_remote_udp_port_cmd);
32297 + install_element (LDP_IF_NODE, &ldp_if_max_pdu_cmd);
32298 + install_element (LDP_IF_NODE, &no_ldp_if_max_pdu_cmd);
32300 + install_element (LDP_IF_NODE, &ldp_if_hello_interval_cmd);
32301 + install_element (LDP_IF_NODE, &no_ldp_if_hello_interval_cmd);
32303 + install_element (LDP_IF_NODE, &ldp_if_keepalive_interval_cmd);
32304 + install_element (LDP_IF_NODE, &no_ldp_if_keepalive_interval_cmd);
32306 +#if 0
32307 + install_element (LDP_IF_NODE, &ldp_if_loop_detect_mode_cmd);
32308 + install_element (LDP_IF_NODE, &no_ldp_if_loop_detect_mode_cmd);
32309 +#endif
32311 + install_element (LDP_IF_NODE, &ldp_if_max_session_attempt_cmd);
32312 + install_element (LDP_IF_NODE, &no_ldp_if_max_session_attempt_cmd);
32314 + install_element (LDP_IF_NODE, &ldp_if_max_path_vector_cmd);
32315 + install_element (LDP_IF_NODE, &no_ldp_if_max_path_vector_cmd);
32317 + install_element (LDP_IF_NODE, &ldp_if_max_hop_count_cmd);
32318 + install_element (LDP_IF_NODE, &no_ldp_if_max_hop_count_cmd);
32320 + install_element (LDP_IF_NODE, &ldp_if_max_label_requests_cmd);
32321 + install_element (LDP_IF_NODE, &no_ldp_if_max_label_requests_cmd);
32323 + install_element (LDP_IF_NODE, &ldp_if_distribution_mode_cmd);
32324 + install_element (LDP_IF_NODE, &no_ldp_if_distribution_mode_cmd);
32326 + install_element (LDP_IF_NODE, &ldp_if_ttl_less_domain_cmd);
32327 + install_element (LDP_IF_NODE, &no_ldp_if_ttl_less_domain_cmd);
32329 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_vty.h quagga-mpls/ldpd/ldp_vty.h
32330 --- quagga/ldpd/ldp_vty.h 1969-12-31 18:00:00.000000000 -0600
32331 +++ quagga-mpls/ldpd/ldp_vty.h 2006-08-09 22:02:25.000000000 -0500
32332 @@ -0,0 +1,31 @@
32333 +#ifndef LDP_VTY_H
32334 +#define LDP_VTY_H
32336 +#include "ldp_interface.h"
32338 +void ldp_vty_show_init();
32339 +void ldp_vty_if_init();
32340 +void ldp_vty_init();
32342 +#define VTY_GET_UINT32(NAME,V,STR) \
32343 +{ \
32344 + char *endptr = NULL; \
32345 + (V) = strtoul ((STR), &endptr, 10); \
32346 + if (*endptr != '\0' || ((V) == ULONG_MAX && errno == ERANGE)) \
32347 + { \
32348 + vty_out (vty, "%% Invalid %s value%s", NAME, VTY_NEWLINE); \
32349 + return CMD_WARNING; \
32350 + } \
32353 +#define VTY_GET_UINT32_RANGE(NAME,V,STR,IMIN,IMAX) \
32354 +{ \
32355 + VTY_GET_UINT32(NAME,V,STR); \
32356 + if (((V) < IMIN) || ((V) > IMAX)) \
32357 + { \
32358 + vty_out (vty, "%% Invalid %s value. Valid range is (%d ... %d)%s", \
32359 + NAME, IMIN, IMAX, VTY_NEWLINE); \
32360 + return CMD_WARNING; \
32361 + } \
32363 +#endif
32364 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_zebra.c quagga-mpls/ldpd/ldp_zebra.c
32365 --- quagga/ldpd/ldp_zebra.c 1969-12-31 18:00:00.000000000 -0600
32366 +++ quagga-mpls/ldpd/ldp_zebra.c 2008-05-11 22:26:55.000000000 -0500
32367 @@ -0,0 +1,577 @@
32368 +#include <zebra.h>
32370 +#include "command.h"
32371 +#include "prefix.h"
32372 +#include "stream.h"
32373 +#include "table.h"
32374 +#include "memory.h"
32375 +#include "zclient.h"
32376 +#include "linklist.h"
32377 +#include "log.h"
32379 +#include "ldp_cfg.h"
32380 +#include "mpls_compare.h"
32382 +#include "ldp.h"
32383 +#include "impl_fib.h"
32384 +#include "impl_ifmgr.h"
32385 +#include "impl_mpls.h"
32386 +#include "ldp_interface.h"
32387 +#include "mpls_mpls_impl.h"
32389 +/* All information about zebra. */
32390 +struct zclient *zclient = NULL;
32391 +struct list *pending_out_segment = NULL;
32392 +struct list *pending_ftn = NULL;
32393 +struct list *pending_xc = NULL;
32395 +/* For registering threads. */
32396 +extern struct thread_master *master;
32398 +struct prefix router_id;
32400 +/* Router-id update message from zebra. */
32401 +static int ldp_router_id_update_zebra(int command, struct zclient *zclient,
32402 + zebra_size_t length) {
32403 + struct ldp *ldp = ldp_get();
32405 + zebra_router_id_update_read(zclient->ibuf,&router_id);
32407 + zlog_info("router-id change %s",
32408 + inet_ntoa(router_id.u.prefix4));
32410 + if (ldp && ldp->lsr_id_is_static != MPLS_BOOL_TRUE)
32411 + ldp_router_id_update(ldp, &router_id);
32412 + return 0;
32415 +/* Inteface addition message from zebra. */
32416 +static int ldp_interface_add(int command, struct zclient *zclient,
32417 + zebra_size_t length) {
32418 + struct interface *ifp;
32420 + if (!(ifp = zebra_interface_add_read(zclient->ibuf))) {
32421 + return 1;
32424 + zlog_info("interface add %s index %d flags %ld metric %d mtu %d",
32425 + ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
32427 + return 0;
32430 +/* this is not the same as ldp_interface_delete() which is found in
32431 + * ldp_interface.c
32432 + */
32433 +static int ldp_interface_deletez(int command, struct zclient *zclient,
32434 + zebra_size_t length) {
32435 + struct interface *ifp;
32436 + struct stream *s;
32438 + s = zclient->ibuf;
32439 + /* zebra_interface_state_read() updates interface structure in iflist */
32440 + ifp = zebra_interface_state_read(s);
32442 + if (ifp == NULL) {
32443 + return 0;
32446 + if (if_is_up(ifp)) {
32447 + zlog_warn("got delete of %s, but interface is still up",
32448 + ifp->name);
32451 + zlog_info("interface delete %s index %d flags %ld metric %d mtu %d",
32452 + ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
32454 + return 0;
32457 +struct interface * zebra_interface_if_lookup(struct stream *s) {
32458 + struct interface *ifp;
32459 + u_char ifname_tmp[INTERFACE_NAMSIZ];
32461 + /* Read interface name. */
32462 + stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
32464 + /* Lookup this by interface index. */
32465 + ifp = if_lookup_by_name(ifname_tmp);
32467 + /* If such interface does not exist, indicate an error */
32468 + if (!ifp) {
32469 + return NULL;
32472 + return ifp;
32475 +static int ldp_interface_state_up(int command, struct zclient *zclient,
32476 + zebra_size_t length) {
32477 + struct interface *ifp;
32478 + struct interface if_tmp;
32480 + ifp = zebra_interface_if_lookup(zclient->ibuf);
32481 + if (ifp == NULL) {
32482 + return 0;
32485 + /* Interface is already up. */
32486 + if (if_is_up (ifp)) {
32487 + /* Temporarily keep ifp values. */
32488 + memcpy (&if_tmp, ifp, sizeof (struct interface));
32490 + zebra_interface_if_set_value (zclient->ibuf, ifp);
32492 + zlog_info ("Interface[%s] state update.", ifp->name);
32494 + return 0;
32497 + zebra_interface_if_set_value(zclient->ibuf, ifp);
32499 + zlog_info ("Interface[%s] state change to up.", ifp->name);
32501 + ldp_interface_up(ifp->info);
32503 + return 0;
32506 +static int ldp_interface_state_down(int command, struct zclient *zclient,
32507 + zebra_size_t length) {
32508 + struct interface *ifp;
32510 + ifp = zebra_interface_state_read (zclient->ibuf);
32511 + if (ifp == NULL) {
32512 + return 0;
32515 + zlog_info ("Interface[%s] state change to down.", ifp->name);
32517 + ldp_interface_down(ifp->info);
32519 + return 0;
32522 +void prefix2mpls_inet_addr(struct prefix *p, struct mpls_inet_addr *a)
32524 + a->type = MPLS_FAMILY_IPV4;
32525 + a->u.ipv4 = (uint32_t)ntohl(p->u.prefix4.s_addr);
32528 +void zebra_prefix2mpls_fec(struct prefix *p, mpls_fec *fec)
32530 + fec->u.prefix.length = p->prefixlen;
32531 + fec->type = MPLS_FEC_PREFIX;
32532 + fec->u.prefix.network.type = MPLS_FAMILY_IPV4;
32533 + fec->u.prefix.network.u.ipv4 = ntohl(p->u.prefix4.s_addr);
32536 +void mpls_fec2zebra_prefix(mpls_fec *lp, struct prefix *p)
32538 + p->family = AF_INET;
32539 + switch(lp->type) {
32540 + case MPLS_FEC_PREFIX:
32541 + p->prefixlen = lp->u.prefix.length;
32542 + p->u.prefix4.s_addr = htonl(lp->u.prefix.network.u.ipv4);
32543 + break;
32544 + case MPLS_FEC_HOST:
32545 + p->prefixlen = 32;
32546 + p->u.prefix4.s_addr = htonl(lp->u.host.u.ipv4);
32547 + break;
32548 + default:
32549 + MPLS_ASSERT(0);
32550 + break;
32554 +static int ldp_interface_address_add(int command, struct zclient *zclient,
32555 + zebra_size_t length) {
32556 + struct ldp *ldp = ldp_get();
32557 + struct connected *c;
32558 + struct interface *ifp;
32559 + struct prefix *p;
32560 + struct ldp_addr addr;
32561 + struct ldp_if iff;
32562 + struct ldp_interface *li;
32564 + c = zebra_interface_address_read(command, zclient->ibuf);
32565 + if (c == NULL || c->address->family != AF_INET) {
32566 + return 0;
32569 + ifp = c->ifp;
32570 + p = c->address;
32572 + /* Don't register addresses connected to the loopback interface */
32573 + if (if_is_loopback(ifp))
32574 + return 0;
32576 + zlog_info("address add %s to interface %s(%p)",inet_ntoa(p->u.prefix4),
32577 + ifp->name, ifp);
32579 + if (ldp) {
32580 + prefix2mpls_inet_addr(p, &addr.address);
32581 + iff.handle = ifp;
32582 + ldp_cfg_if_addr_set(ldp->h, &iff, &addr, LDP_CFG_ADD);
32584 + li = ifp->info;
32585 + if (ldp->trans_addr == LDP_TRANS_ADDR_STATIC_INTERFACE &&
32586 + !strncmp(ldp->trans_addr_ifname,ifp->name,IFNAMSIZ + 1)) {
32587 + ldp_global g;
32589 + zlog_info("updating global transport address");
32590 + g.transport_address.u.ipv4 = ntohl(if_ipv4_src_address (ifp));
32591 + g.transport_address.type =
32592 + (g.transport_address.u.ipv4)?MPLS_FAMILY_IPV4:MPLS_FAMILY_NONE;
32593 + ldp_admin_state_start(ldp);
32594 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_TRANS_ADDR);
32595 + ldp_admin_state_finish(ldp);
32597 + if (ldp->trans_addr == LDP_TRANS_ADDR_INTERFACE) {
32598 + zlog_info("updating entity transport address");
32599 + li->entity.transport_address.u.ipv4 =
32600 + ntohl(if_ipv4_src_address (ifp));
32602 + li->entity.transport_address.type =
32603 + li->entity.transport_address.u.ipv4 ?
32604 + MPLS_FAMILY_IPV4 : MPLS_FAMILY_NONE;
32606 + if (li->entity.index) {
32607 + ldp_interface_admin_state_start(li);
32608 + ldp_cfg_entity_set(ldp->h, &li->entity,
32609 + LDP_ENTITY_CFG_TRANS_ADDR);
32610 + ldp_interface_admin_state_finish(li);
32615 + return 0;
32618 +static int ldp_interface_address_delete(int command, struct zclient *zclient,
32619 + zebra_size_t length) {
32620 + struct ldp *ldp = ldp_get();
32621 + struct connected *c;
32622 + struct interface *ifp;
32623 + struct prefix *p;
32624 + struct ldp_addr addr;
32625 + struct ldp_if iff;
32626 + struct ldp_interface *li;
32628 + c = zebra_interface_address_read(command, zclient->ibuf);
32629 + if (c == NULL || c->address->family != AF_INET) {
32630 + return 0;
32633 + ifp = c->ifp;
32634 + p = c->address;
32636 + zlog_info("address delete %s from interface %s",
32637 + inet_ntoa(p->u.prefix4), ifp->name);
32639 + if (ldp) {
32640 + prefix2mpls_inet_addr(p, &addr.address);
32641 + iff.handle = ifp;
32642 + ldp_cfg_if_addr_set(ldp->h, &iff, &addr, LDP_CFG_DEL);
32644 + li = ifp->info;
32645 + if (ldp->trans_addr == LDP_TRANS_ADDR_STATIC_INTERFACE &&
32646 + !strncmp(ldp->trans_addr_ifname,ifp->name,IFNAMSIZ + 1)) {
32647 + ldp_global g;
32649 + zlog_info("updating global transport address");
32650 + g.transport_address.u.ipv4 = ntohl(if_ipv4_src_address (ifp));
32651 + g.transport_address.type =
32652 + (g.transport_address.u.ipv4)?MPLS_FAMILY_IPV4:MPLS_FAMILY_NONE;
32653 + ldp_admin_state_start(ldp);
32654 + ldp_cfg_global_set(ldp->h,&g, LDP_GLOBAL_CFG_TRANS_ADDR);
32655 + ldp_admin_state_finish(ldp);
32657 + if (ldp->trans_addr == LDP_TRANS_ADDR_INTERFACE) {
32658 + zlog_info("updating entity transport address");
32659 + li->entity.transport_address.u.ipv4 =
32660 + ntohl(if_ipv4_src_address (ifp));
32662 + li->entity.transport_address.type =
32663 + li->entity.transport_address.u.ipv4 ?
32664 + MPLS_FAMILY_IPV4 : MPLS_FAMILY_NONE;
32666 + if (li->entity.index) {
32667 + ldp_interface_admin_state_start(li);
32668 + ldp_cfg_entity_set(ldp->h, &li->entity,
32669 + LDP_ENTITY_CFG_TRANS_ADDR);
32670 + ldp_interface_admin_state_finish(li);
32675 + connected_free(c);
32677 + return 0;
32680 +static int ldp_zebra_read_ipv4(int cmd, struct zclient *client,
32681 + zebra_size_t length) {
32682 + struct prefix_ipv4 prefix;
32683 + struct zapi_ipv4 api;
32684 + int i = 0;
32685 + int j;
32687 + struct mpls_nexthop nexthop[8];
32688 + struct ldp *ldp = ldp_get();
32689 + struct mpls_fec fec;
32690 + struct stream *s;
32691 + struct in_addr tmp;
32693 + memset(&api,0,sizeof(api));
32694 + memset(nexthop,0,sizeof(nexthop));
32696 + s = client->ibuf;
32697 + zapi_ipv4_read (s, length, &api, &prefix);
32699 + zlog_info("route %s/%d", inet_ntoa(prefix.prefix), prefix.prefixlen);
32701 + if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
32703 + for (i = 0; i < api.nexthop_num; i++)
32705 + if (api.type == ZEBRA_ROUTE_CONNECT)
32707 + nexthop[i].attached = MPLS_BOOL_TRUE;
32708 + zlog_info("\tattached");
32710 + nexthop[i].ip.type = MPLS_FAMILY_IPV4;
32711 + if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
32712 + nexthop[i].distance = api.message;
32713 + if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
32714 + nexthop[i].metric = api.metric;
32715 + if (CHECK_FLAG (api.nexthop[i].type, ZEBRA_NEXTHOP_IPV4))
32717 + nexthop[i].ip.u.ipv4 = ntohl(api.nexthop[i].gw.ipv4.s_addr);
32718 + nexthop[i].type |= MPLS_NH_IP;
32719 + tmp.s_addr = htonl(nexthop[i].ip.u.ipv4);
32720 + zlog_info("\tnexthop %s", inet_ntoa(tmp));
32722 + if (CHECK_FLAG (api.nexthop[i].type, ZEBRA_NEXTHOP_IFINDEX))
32724 + nexthop[i].if_handle =
32725 + if_lookup_by_index(api.nexthop[i].intf.index);
32726 + if (nexthop[i].if_handle)
32728 + nexthop[i].type |= MPLS_NH_IF;
32729 + zlog_info("\tifindex %d", nexthop[i].if_handle->ifindex);
32735 + zebra_prefix2mpls_fec((struct prefix*)&prefix, &fec);
32736 + for (j = 0; j < i; j++) {
32737 + if (cmd == ZEBRA_IPV4_ROUTE_ADD) {
32738 + zlog_info("\tadd");
32739 + if ((ldp_cfg_fec_get(ldp->h, &fec, 0) != MPLS_SUCCESS) ||
32740 + (fec.is_route == MPLS_BOOL_FALSE)) {
32741 + if (ldp_cfg_fec_set(ldp->h, &fec, LDP_CFG_ADD) != MPLS_SUCCESS) {
32742 + MPLS_ASSERT(0);
32745 + if (ldp_cfg_fec_nexthop_get(ldp->h, &fec, &nexthop[j],
32746 + LDP_FEC_CFG_BY_INDEX) != MPLS_SUCCESS) {
32747 + if (ldp_cfg_fec_nexthop_set(ldp->h, &fec, &nexthop[j],
32748 + LDP_CFG_ADD|LDP_FEC_CFG_BY_INDEX) != MPLS_SUCCESS) {
32749 + MPLS_ASSERT(0);
32751 + } else {
32752 + /*
32753 + * already exists ... looks like we can get the same route sent
32754 + * to us twice ... multiple protocols?
32755 + MPLS_ASSERT(0);
32756 + */
32758 + } else {
32759 + zlog_info("\tdelete");
32760 + if ((ldp_cfg_fec_get(ldp->h, &fec, 0) == MPLS_SUCCESS) &&
32761 + (fec.is_route == MPLS_BOOL_TRUE)) {
32762 + if (ldp_cfg_fec_nexthop_get(ldp->h, &fec, &nexthop[j],
32763 + LDP_FEC_CFG_BY_INDEX) == MPLS_SUCCESS) {
32764 + if (ldp_cfg_fec_nexthop_set(ldp->h, &fec, &nexthop[j],
32765 + LDP_FEC_CFG_BY_INDEX|LDP_CFG_DEL|
32766 + LDP_FEC_NEXTHOP_CFG_BY_INDEX) != MPLS_SUCCESS) {
32767 + MPLS_ASSERT(0);
32769 + } else {
32770 + MPLS_ASSERT(0);
32772 + if (ldp_cfg_fec_set(ldp->h, &fec, LDP_CFG_DEL|LDP_FEC_CFG_BY_INDEX) !=
32773 + MPLS_SUCCESS) {
32774 + MPLS_ASSERT(0);
32776 + } else {
32777 + MPLS_ASSERT(0);
32781 + return 0;
32784 +static int ldp_zebra_read_ipv6(int cmd, struct zclient *client,
32785 + zebra_size_t length) {
32786 + struct prefix_ipv6 prefix;
32787 + struct zapi_ipv6 api;
32789 + memset(&api,0,sizeof(api));
32790 + zapi_ipv6_route_read (client, length, &api, &prefix);
32792 + return 0;
32795 +static int ldp_xc_read(int cmd, struct zclient *client, zebra_size_t size) {
32796 + struct zapi_mpls_xc api;
32797 + mpls_xc_stream_read(client->ibuf, &api);
32798 + return 0;
32801 +static int ldp_in_segment_read(int cmd, struct zclient *client,
32802 + zebra_size_t size) {
32803 + struct zapi_mpls_in_segment api;
32804 + mpls_in_segment_stream_read(client->ibuf, &api);
32805 + return 0;
32808 +static int ldp_out_segment_read(int cmd, struct zclient *client,
32809 + zebra_size_t size) {
32810 + struct zapi_mpls_out_segment api;
32811 + struct listnode *n;
32812 + struct listnode *nn;
32813 + mpls_outsegment *o;
32814 + struct pending_ftn_data *fn;
32815 + struct pending_xc_data *x;
32817 + mpls_out_segment_stream_read(client->ibuf, &api);
32819 + for (ALL_LIST_ELEMENTS(pending_out_segment, n, nn, o)) {
32820 + if (api.req == o->handle) {
32821 + zlog_info("found pending NHLFE: %p", o);
32822 + o->handle = api.index;
32823 + list_delete_node(pending_out_segment,n);
32824 + goto ftn;
32827 + zlog_info("requested out segment %d not in list", api.req);
32828 + return 0;
32830 +ftn:
32831 + /* if we've gotten this for then the o->handle is not the proper index */
32832 + for (ALL_LIST_ELEMENTS(pending_ftn, n, nn, fn)) {
32833 + if (api.index == fn->o->handle) {
32834 + mpls_mpls_fec2out_add(fn->h, fn->f, fn->o);
32835 + list_delete_node(pending_ftn,n);
32836 + break;
32839 + for (ALL_LIST_ELEMENTS(pending_xc, n, nn, x)) {
32840 + if (api.index == x->o->handle) {
32841 + mpls_mpls_xconnect_add(x->h, x->i, x->o);
32842 + list_delete_node(pending_xc,n);
32843 + break;
32846 + return 0;
32849 +static int ldp_labelspace_read(int cmd, struct zclient *client,
32850 + zebra_size_t size) {
32851 + struct zapi_mpls_labelspace api;
32852 + struct interface *ifp;
32853 + struct ldp_interface *li;
32854 + int labelspace;
32856 + mpls_labelspace_stream_read(client->ibuf, &api);
32857 + ifp = if_lookup_by_name(api.ifname);
32859 + if (ifp) {
32860 + labelspace = ifp->mpls_labelspace;
32861 + ifp->mpls_labelspace = api.labelspace;
32863 + if (ifp->info) {
32864 + li = ifp->info;
32866 + if (api.labelspace < 0) {
32867 + if (li->configured == MPLS_BOOL_TRUE)
32868 + ldp_interface_shutdown (li);
32869 + } else {
32870 + if (labelspace >= 0) {
32871 + if (li->configured == MPLS_BOOL_TRUE)
32872 + ldp_interface_shutdown (li);
32874 + if (li->configured == MPLS_BOOL_TRUE)
32875 + ldp_interface_startup (li);
32879 + return 0;
32882 +static int ldp_ftn_read(int cmd, struct zclient *client, zebra_size_t size) {
32883 + struct zapi_mpls_ftn api;
32884 + mpls_ftn_stream_read(client->ibuf, &api);
32885 + return 0;
32888 +void ldp_zebra_startup() {
32889 + int i;
32890 + for (i = 0;i < ZEBRA_ROUTE_MAX;i++) {
32891 + if (i != ZEBRA_ROUTE_LDP)
32892 + zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient,i);
32896 +void ldp_zebra_shutdown() {
32897 + int i;
32898 + for (i = 0;i < ZEBRA_ROUTE_MAX;i++) {
32899 + if (i != ZEBRA_ROUTE_LDP)
32900 + zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient,i);
32904 +void pending_delete(void *m) {
32905 + XFREE(MTYPE_TMP, m);
32908 +void ldp_zebra_init() {
32910 + pending_out_segment = list_new();
32911 + pending_ftn = list_new();
32912 + pending_ftn->del = pending_delete;
32913 + pending_xc = list_new();
32914 + pending_xc->del = pending_delete;
32916 + /* Allocate zebra structure. */
32917 + zclient = zclient_new();
32918 + zclient_init(zclient, ZEBRA_ROUTE_LDP);
32919 + zclient->router_id_update = ldp_router_id_update_zebra;
32920 + zclient->interface_add = ldp_interface_add;
32921 + zclient->interface_delete = ldp_interface_deletez;
32922 + zclient->interface_up = ldp_interface_state_up;
32923 + zclient->interface_down = ldp_interface_state_down;
32924 + zclient->interface_address_add = ldp_interface_address_add;
32925 + zclient->interface_address_delete = ldp_interface_address_delete;
32926 + zclient->ipv4_route_add = ldp_zebra_read_ipv4;
32927 + zclient->ipv4_route_delete = ldp_zebra_read_ipv4;
32929 + *zclient->ipv6_route_add = ldp_zebra_read_ipv6;
32930 + *zclient->ipv6_route_delete = ldp_zebra_read_ipv6;
32931 + */
32932 + zclient->mpls_xc_add = ldp_xc_read;
32933 + zclient->mpls_xc_delete = ldp_xc_read;
32934 + zclient->mpls_in_segment_add = ldp_in_segment_read;
32935 + zclient->mpls_in_segment_delete = ldp_in_segment_read;
32936 + zclient->mpls_out_segment_add = ldp_out_segment_read;
32937 + zclient->mpls_out_segment_delete = ldp_out_segment_read;
32938 + zclient->mpls_labelspace_add = ldp_labelspace_read;
32939 + zclient->mpls_labelspace_delete = ldp_labelspace_read;
32940 + zclient->mpls_ftn_add = ldp_ftn_read;
32941 + zclient->mpls_ftn_delete = ldp_ftn_read;
32943 + memset(&router_id, 0, sizeof(router_id));
32945 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/ldp_zebra.h quagga-mpls/ldpd/ldp_zebra.h
32946 --- quagga/ldpd/ldp_zebra.h 1969-12-31 18:00:00.000000000 -0600
32947 +++ quagga-mpls/ldpd/ldp_zebra.h 2006-08-09 22:02:25.000000000 -0500
32948 @@ -0,0 +1,17 @@
32949 +#ifndef _ZEBRA_LDP_ZEBRA_H
32950 +#define _ZEBRA_LDP_ZEBRA_H
32952 +#include "prefix.h"
32954 +#include "ldp_struct.h"
32956 +extern struct prefix router_id;
32958 +void ldp_zebra_init();
32959 +void prefix2mpls_inet_addr(struct prefix *p, struct mpls_inet_addr *a);
32960 +void zebra_prefix2mpls_fec(struct prefix *p, mpls_fec *fec);
32961 +void mpls_fec2zebra_prefix(mpls_fec *fec, struct prefix *p);
32962 +void ldp_zebra_startup();
32963 +void ldp_zebra_shutdown();
32965 +#endif
32966 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/Makefile.am quagga-mpls/ldpd/Makefile.am
32967 --- quagga/ldpd/Makefile.am 1969-12-31 18:00:00.000000000 -0600
32968 +++ quagga-mpls/ldpd/Makefile.am 2006-08-09 22:02:24.000000000 -0500
32969 @@ -0,0 +1,60 @@
32970 +# Process this file with automake to produce Makefile.in.
32972 +INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib
32973 +DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\"
32974 +INSTALL_SDATA=@INSTALL@ -m 600
32976 +sbin_PROGRAMS = ldpd
32978 +ldpd_SOURCES = \
32979 +impl_fib.c impl_ifmgr.c impl_lock.c impl_mm.c impl_mpls.c \
32980 +impl_policy.c impl_socket.c impl_timer.c impl_tree.c \
32981 +ldp_zebra.c ldp_main.c \
32982 +ldp.c ldp_interface.c ldp_vty.c ldp_remote_peer.c l2cc_interface.c \
32983 +ldp_addr.c ldp_adj.c \
32984 +ldp_attr.c ldp_buf.c ldp_cfg.c ldp_entity.c ldp_fec.c ldp_global.c \
32985 +ldp_hello.c ldp_hop.c ldp_hop_list.c ldp_if.c ldp_inet_addr.c \
32986 +ldp_init.c ldp_inlabel.c ldp_keepalive.c ldp_label_abort.c \
32987 +ldp_label_mapping.c ldp_label_rel_with.c ldp_label_request.c \
32988 +ldp_mesg.c ldp_nortel.c ldp_notif.c ldp_outlabel.c \
32989 +ldp_pdu_setup.c ldp_peer.c \
32990 +ldp_resource.c ldp_session.c ldp_state_funcs.c \
32991 +ldp_state_machine.c ldp_tunnel.c ldp_nexthop.c\
32992 +mpls_compare.c
32995 +noinst_HEADERS = \
32996 +ldp_zebra.h \
32997 +ldp.h ldp_interface.h ldp_vty.h ldp_remote_peer.h l2cc_interface.h \
32998 +ldp_addr.h ldp_adj.h ldp_attr.h ldp_buf.h ldp_cfg.h \
32999 +ldp_defaults.h ldp_entity.h ldp_fec.h \
33000 +ldp_global.h mpls_handle_type.h ldp_hello.h ldp_hop.h \
33001 +ldp_hop_list.h ldp_if.h ldp_inet_addr.h \
33002 +ldp_init.h ldp_inlabel.h ldp_keepalive.h ldp_label_abort.h \
33003 +ldp_label_mapping.h ldp_label_rel_with.h ldp_label_request.h \
33004 +ldp_mesg.h ldp_nortel.h ldp_notif.h ldp_outlabel.h ldp_pdu.h ldp_nexthop.h \
33005 +ldp_pdu_setup.h ldp_peer.h mpls_refcnt.h ldp_resource.h \
33006 +ldp_session.h ldp_state_machine.h ldp_struct.h ldp_tunnel.h \
33007 +mpls_tree_impl.h mpls_mm_impl.h mpls_mpls_impl.h mpls_trace_impl.h \
33008 +mpls_assert.h mpls_fib_impl.h mpls_ifmgr_impl.h mpls_list.h mpls_lock_impl.h \
33009 +mpls_policy_impl.h mpls_socket_impl.h mpls_timer_impl.h mpls_trace.h \
33010 +mpls_struct.h mpls_compare.h mpls_bitfield.h
33012 +ldpd_LDADD = -L../lib -lzebra @LIBCAP@
33014 +sysconf_DATA = ldpd.conf.sample
33016 +EXTRA_DIST = $(sysconf_DATA)
33018 +install-sysconfDATA: $(sysconf_DATA)
33019 + @$(NORMAL_INSTALL)
33020 + $(mkinstalldirs) $(DESTDIR)$(sysconfdir)
33021 + @list='$(sysconf_DATA)'; for p in $$list; do \
33022 + if test -f $(srcdir)/$$p; then \
33023 + echo " $(INSTALL_SDATA) $(srcdir)/$$p $(DESTDIR)$(sysconfdir)/$$p"; \
33024 + $(INSTALL_SDATA) $(srcdir)/$$p $(DESTDIR)$(sysconfdir)/$$p; \
33025 + else if test -f $$p; then \
33026 + echo " $(INSTALL_SDATA) $$p $(DESTDIR)$(sysconfdir)/$$p"; \
33027 + $(INSTALL_SDATA) $$p $(DESTDIR)$(sysconfdir)/$$p; \
33028 + fi; fi; \
33029 + done
33030 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_assert.h quagga-mpls/ldpd/mpls_assert.h
33031 --- quagga/ldpd/mpls_assert.h 1969-12-31 18:00:00.000000000 -0600
33032 +++ quagga-mpls/ldpd/mpls_assert.h 2006-08-09 21:56:09.000000000 -0500
33033 @@ -0,0 +1,17 @@
33036 + * Copyright (C) James R. Leu 2002
33037 + * jleu@mindspring.com
33039 + * This software is covered under the LGPL, for more
33040 + * info check out http://www.gnu.org/copyleft/lgpl.html
33041 + */
33043 +#ifndef _MPLS_ASSERT_H_
33044 +#define _MPLS_ASSERT_H_
33046 +#include <assert.h>
33048 +#define MPLS_ASSERT(x) assert(x)
33050 +#endif
33051 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_bitfield.h quagga-mpls/ldpd/mpls_bitfield.h
33052 --- quagga/ldpd/mpls_bitfield.h 1969-12-31 18:00:00.000000000 -0600
33053 +++ quagga-mpls/ldpd/mpls_bitfield.h 2006-08-09 21:56:09.000000000 -0500
33054 @@ -0,0 +1,31 @@
33056 + * Copyright (C) James R. Leu 2003
33057 + * jleu@mindspring.com
33059 + * This software is covered under the LGPL, for more
33060 + * info check out http://www.gnu.org/copyleft/lgpl.html
33061 + */
33063 +#ifndef MPLS_BITFIELD_H
33064 +#define MPLS_BITFILED_H
33066 +#include <endian.h>
33068 +#if (__BYTE_ORDER == __LITTLE_ENDIAN)
33069 +#define LITTLE_ENDIAN_BYTE_ORDER 1
33070 +#endif
33072 +/* macros to handle different byte orders (little endian or big endian) */
33073 +#ifdef LITTLE_ENDIAN_BYTE_ORDER
33074 +#define BITFIELDS_ASCENDING_2(X, Y) Y; X;
33075 +#define BITFIELDS_ASCENDING_3(X, Y, Z) Z; Y; X;
33076 +#define BITFIELDS_ASCENDING_4(X, Y, Z, W) W; Z; Y; X;
33077 +#define BITFIELDS_ASCENDING_7(X, Y, Z, W, U, A, B) B; A; U; W; Z; Y; X;
33078 +# else
33079 +#define BITFIELDS_ASCENDING_2(X, Y) X; Y;
33080 +#define BITFIELDS_ASCENDING_3(X, Y, Z) X; Y; Z;
33081 +#define BITFIELDS_ASCENDING_4(X, Y, Z, W) X; Y; Z; W;
33082 +#define BITFIELDS_ASCENDING_7(X, Y, Z, W, U, A, B) X; Y; Z; W; U; A; B;
33083 +#endif /* LITTLE_ENDIAN_BYTE_ORDER */
33085 +#endif
33086 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_compare.c quagga-mpls/ldpd/mpls_compare.c
33087 --- quagga/ldpd/mpls_compare.c 1969-12-31 18:00:00.000000000 -0600
33088 +++ quagga-mpls/ldpd/mpls_compare.c 2006-08-09 21:56:09.000000000 -0500
33089 @@ -0,0 +1,148 @@
33090 +#include "mpls_struct.h"
33091 +#include "mpls_assert.h"
33093 +int mpls_inet_addr_compare(struct mpls_inet_addr *addr1,
33094 + struct mpls_inet_addr *addr2) {
33095 + if (addr1->type != addr2->type) {
33096 + return 1;
33098 + switch(addr1->type) {
33099 + case MPLS_FAMILY_IPV4:
33100 + if (addr1->u.ipv4 != addr2->u.ipv4) {
33101 + return addr1->u.ipv4 > addr2->u.ipv4 ? 1 : -1;
33103 + break;
33104 + case MPLS_FAMILY_IPV6:
33105 + return memcmp(addr1->u.ipv6, addr2->u.ipv6, 16);
33106 + default:
33107 + MPLS_ASSERT(0);
33109 + return 0;
33112 +int mpls_nexthop_compare(struct mpls_nexthop *nh1, struct mpls_nexthop *nh2) {
33113 + int retval = 0;
33114 + int match = 0;
33116 + if (nh1->type != nh2->type) {
33117 + return 1;
33119 + if (nh1->type & MPLS_NH_IP) {
33120 + match++;
33121 + if ((retval = mpls_inet_addr_compare(&nh1->ip, &nh2->ip))) {
33122 + return retval;
33125 + if (nh1->type & MPLS_NH_IF) {
33126 + match++;
33127 + if ((retval = mpls_if_handle_compare(nh1->if_handle, nh2->if_handle))) {
33128 + return retval;
33131 + if (nh1->type & MPLS_NH_OUTSEGMENT) {
33132 + match++;
33133 + if ((retval = mpls_outsegment_handle_compare(nh1->outsegment_handle,
33134 + nh2->outsegment_handle))) {
33135 + return retval;
33139 + if (!match) {
33140 + return 1;
33142 + return 0;
33145 +int mpls_label_struct_compare(struct mpls_label_struct* l1,
33146 + struct mpls_label_struct* l2) {
33147 + if (l1->type != l2->type) {
33148 + return 1;
33150 + switch(l1->type) {
33151 + case MPLS_LABEL_TYPE_GENERIC:
33152 + if (l1->u.gen != l2->u.gen) {
33153 + return (l1->u.gen > l2->u.gen) ? 1 : -1;
33155 + break;
33156 + case MPLS_LABEL_TYPE_ATM:
33157 + if (l1->u.atm.vpi != l2->u.atm.vpi) {
33158 + return (l1->u.atm.vpi > l2->u.atm.vpi) ? 1 : -1;
33160 + if (l1->u.atm.vci != l2->u.atm.vci) {
33161 + return (l1->u.atm.vci > l2->u.atm.vci) ? 1 : -1;
33163 + break;
33164 + case MPLS_LABEL_TYPE_FR:
33165 + if (l1->u.fr.len != l2->u.fr.len) {
33166 + return (l1->u.fr.dlci > l2->u.fr.dlci) ? 1 : -1;
33168 + if (l1->u.fr.dlci != l2->u.fr.dlci) {
33169 + return (l1->u.fr.len > l2->u.fr.len) ? 1 : -1;
33171 + break;
33172 + default:
33173 + MPLS_ASSERT(0);
33175 + return 0;
33178 +int mpls_dest_compare(struct mpls_dest* d1, struct mpls_dest* d2) {
33179 + int retval;
33180 + if ((retval = mpls_inet_addr_compare(&d1->addr, &d2->addr))) {
33181 + return retval;
33183 + if (d1->port != d2->port) {
33184 + return (d1->port > d2->port) ? 1 : -1;
33186 + if ((retval = mpls_if_handle_compare(d1->if_handle, d2->if_handle))) {
33187 + return retval;
33189 + return 0;
33192 +int mpls_range_compare(struct mpls_range* r1, struct mpls_range* r2) {
33193 + int retval;
33194 + if ((retval = mpls_label_struct_compare(&r1->min, &r2->min))) {
33195 + return retval;
33197 + if ((retval = mpls_label_struct_compare(&r1->max, &r2->max))) {
33198 + return retval;
33200 + return 0;
33203 +int mpls_fec_compare(struct mpls_fec* f1, struct mpls_fec* f2) {
33204 + int retval;
33206 + if (f1->type != f2->type) {
33207 + return 1;
33210 + switch(f1->type) {
33211 + case MPLS_FEC_PREFIX:
33212 + if ((retval = mpls_inet_addr_compare(&f1->u.prefix.network,
33213 + &f2->u.prefix.network))) {
33214 + return retval;
33216 + if (f1->u.prefix.length > f2->u.prefix.length) {
33217 + return (f1->u.prefix.length != f2->u.prefix.length) ? 1 : -1;
33219 + break;
33220 + case MPLS_FEC_HOST:
33221 + return mpls_inet_addr_compare(&f1->u.host, &f2->u.host);
33222 + case MPLS_FEC_L2CC:
33223 + if (f1->u.l2cc.connection_id != f2->u.l2cc.connection_id) {
33224 + return (f1->u.l2cc.connection_id>f2->u.l2cc.connection_id) ? 1 : -1;
33226 + if (f1->u.l2cc.group_id != f2->u.l2cc.group_id) {
33227 + return (f1->u.l2cc.group_id > f2->u.l2cc.group_id) ? 1 : -1;
33229 + if (f1->u.l2cc.type != f2->u.l2cc.type) {
33230 + return 1;
33232 + break;
33233 + default:
33234 + MPLS_ASSERT(0);
33236 + return 0;
33238 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_compare.h quagga-mpls/ldpd/mpls_compare.h
33239 --- quagga/ldpd/mpls_compare.h 1969-12-31 18:00:00.000000000 -0600
33240 +++ quagga-mpls/ldpd/mpls_compare.h 2006-08-09 21:56:09.000000000 -0500
33241 @@ -0,0 +1,14 @@
33242 +#ifndef MPLS_COMPARE_H
33243 +#define MPLS_COMPARE_H
33245 +#include "mpls_struct.h"
33247 +int mpls_inet_addr_compare(struct mpls_inet_addr*, struct mpls_inet_addr*);
33248 +int mpls_nexthop_compare(struct mpls_nexthop*, struct mpls_nexthop*);
33249 +int mpls_dest_compare(struct mpls_dest*, struct mpls_dest*);
33250 +int mpls_label_struct_compare(struct mpls_label_struct*,
33251 + struct mpls_label_struct*);
33252 +int mpls_range_compare(struct mpls_range*, struct mpls_range*);
33253 +int mpls_fec_compare(struct mpls_fec*, struct mpls_fec*);
33255 +#endif
33256 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_fib_impl.h quagga-mpls/ldpd/mpls_fib_impl.h
33257 --- quagga/ldpd/mpls_fib_impl.h 1969-12-31 18:00:00.000000000 -0600
33258 +++ quagga-mpls/ldpd/mpls_fib_impl.h 2006-08-09 21:56:09.000000000 -0500
33259 @@ -0,0 +1,75 @@
33262 + * Copyright (C) James R. Leu 2002
33263 + * jleu@mindspring.com
33265 + * This software is covered under the LGPL, for more
33266 + * info check out http://www.gnu.org/copyleft/lgpl.html
33267 + */
33269 +#ifndef _MPLS_FIB_IMPL_H_
33270 +#define _MPLS_FIB_IMPL_H_
33272 +#include "mpls_struct.h"
33275 + * in: handle, cfg, callback,
33276 + * return: mpls_fib_handle
33277 + */
33278 +extern mpls_fib_handle mpls_fib_open(const mpls_instance_handle handle,
33279 + const mpls_cfg_handle cfg);
33282 + * in: handle
33283 + */
33284 +extern void mpls_fib_close(mpls_fib_handle handle);
33287 + * in: handle,num_entry,dest,entry
33288 + * out: entry
33289 + * return: int (number of routes returned in entry)
33290 + */
33291 +extern int mpls_fib_get_route(const mpls_fib_handle handle, const int num_entry,
33292 + const mpls_fec * dest, mpls_fec * entry);
33295 + * in: handle,num_entry,dest,entry
33296 + * out: entry
33297 + * return: int (number of routes returned in entry)
33298 + */
33299 +extern int mpls_fib_get_best_route(const mpls_fib_handle handle,
33300 + const int num_entry, const mpls_fec * dest, mpls_fec * entry);
33303 + * in: handle
33304 + * out: fec, nexthop
33305 + * return: mpls_return_enum
33306 + */
33307 +extern mpls_return_enum mpls_fib_getfirst_route(const mpls_fib_handle handle,
33308 + mpls_fec * fec, mpls_nexthop *nexthop);
33311 + * in: handle, fec, nexthop
33312 + * out: fec, nexthop
33313 + * return: mpls_return_enum
33314 + */
33315 +extern mpls_return_enum mpls_fib_getnext_route(const mpls_fib_handle handle,
33316 + mpls_fec * fec, mpls_nexthop *nexthop);
33319 + * in: handle, fec, owner, data
33320 + * out:
33321 + * return: mpls_return_enum
33322 + */
33323 +extern mpls_return_enum mpls_fib_set_data(mpls_fib_handle handle, mpls_fec *fec,
33324 + mpls_owners_enum owner, void *data);
33327 + * in: handle, fec, owner
33328 + * out: data
33329 + * return: mpls_return_enum
33330 + */
33331 +extern mpls_return_enum mpls_fib_get_data(mpls_fib_handle handle, mpls_fec *fec,
33332 + mpls_owners_enum owner, void **data);
33334 +#endif
33335 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_handle_type.h quagga-mpls/ldpd/mpls_handle_type.h
33336 --- quagga/ldpd/mpls_handle_type.h 1969-12-31 18:00:00.000000000 -0600
33337 +++ quagga-mpls/ldpd/mpls_handle_type.h 2008-02-28 22:57:27.000000000 -0600
33338 @@ -0,0 +1,94 @@
33339 +#ifndef _LDP_HANDLE_TYPE_H_
33340 +#define _LDP_HANDLE_TYPE_H_
33342 +#define MPLS_USE_LSR 0
33344 +#if (__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0))
33345 +#if 0
33346 +typedef unsigned char uint8_t;
33347 +typedef unsigned short uint16_t;
33348 +typedef unsigned int uint32_t;
33349 +#endif
33350 +#else
33351 +#include <stdint.h>
33352 +#endif
33354 +#include <zebra.h>
33355 +#include "if.h"
33357 +struct ldp;
33358 +struct ldp_timer;
33359 +struct ldp_socket;
33361 +#define ptr_verify(x) (x ? MPLS_BOOL_TRUE : MPLS_BOOL_FALSE)
33363 +typedef void *mpls_tree_handle;
33364 +#define mpls_tree_handle_compare(x,y) (x != y)
33365 +#define mpls_tree_handle_verify(x) ptr_verify(x)
33367 +typedef void *mpls_instance_handle;
33368 +#define mpls_instance_handle_compare(x,y) (x != y)
33369 +#define mpls_instance_handle_verify(x) ptr_verify(x)
33371 +typedef struct ldp* mpls_fib_handle;
33372 +#define mpls_fib_handle_compare(x,y) (x != y)
33373 +#define mpls_fib_handle_verify(x) ptr_verify(x)
33375 +typedef int mpls_ifmgr_handle;
33376 +#define mpls_ifmgr_handle_compare(x,y) (x != y)
33377 +#define mpls_ifmgr_handle_verify(x) ptr_verify(x)
33379 +typedef struct interface* mpls_if_handle;
33380 +#define mpls_if_handle_compare(x,y) \
33381 + ((x->ifindex <= 0 && y->ifindex <= 0) ? (x != y) : ((x->ifindex == y->ifindex) ? 0 : (x->ifindex > y->ifindex ? 1 : -1)))
33382 +#define mpls_if_handle_verify(m,x) ptr_verify(x)
33384 +typedef int mpls_timer_mgr_handle;
33385 +#define mpls_timer_mgr_handle_compare(x,y) (x != y)
33386 +#define mpls_timer_mgr_handle_verify(x) ptr_verify(x)
33388 +typedef struct mpls_timer* mpls_timer_handle;
33389 +#define mpls_timer_handle_compare(x,y) (x != y)
33390 +#define mpls_timer_handle_verify(m,x) ptr_verify(x)
33392 +typedef int mpls_socket_mgr_handle;
33393 +#define mpls_socket_mgr_handle_compare(x,y) (x != y)
33394 +#define mpls_socket_mgr_handle_verify(x) MPLS_BOOL_TRUE
33396 +typedef struct mpls_socket* mpls_socket_handle;
33397 +#define mpls_socket_handle_compare(x,y) (x->fd != y->fd)
33398 +#define mpls_socket_handle_verify(m,x) ptr_verify(x)
33400 +typedef int mpls_mpls_handle;
33401 +#define mpls_mpls_handle_compare(x,y) (x != y)
33402 +#define mpls_mpls_handle_verify(x) ptr_verify(x)
33404 +typedef int mpls_insegment_handle;
33405 +#define mpls_insegment_handle_compare(x,y) (x != y)
33406 +#define mpls_insegment_handle_verify(m,x) ptr_verify(x)
33408 +typedef int mpls_outsegment_handle;
33409 +#define mpls_outsegment_handle_compare(x,y) (x != y)
33410 +#define mpls_outsegment_handle_verify(m,x) ptr_verify(x)
33412 +typedef int mpls_xconnect_handle;
33413 +#define mpls_xconnect_handle_compare(x,y) (x != y)
33414 +#define mpls_xconnect_handle_verify(m,x) ptr_verify(x)
33416 +typedef int *mpls_lock_handle;
33417 +#define mpls_lock_handle_compare(x,y) (x != y)
33418 +#define mpls_lock_handle_verify(x) ptr_verify(x)
33420 +typedef int mpls_tunnel_handle;
33421 +#define mpls_tunnel_handle_compare(x,y) (x != y)
33423 +typedef int mpls_policy_handle;
33424 +#define mpls_policy_handle_compare(x,y) (x != y)
33426 +typedef int mpls_trace_handle;
33427 +#define mpls_trace_handle_compare(x,y) (x != y)
33429 +typedef char *mpls_lock_key_type;
33430 +typedef int mpls_size_type;
33432 +#endif
33433 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_ifmgr_impl.h quagga-mpls/ldpd/mpls_ifmgr_impl.h
33434 --- quagga/ldpd/mpls_ifmgr_impl.h 1969-12-31 18:00:00.000000000 -0600
33435 +++ quagga-mpls/ldpd/mpls_ifmgr_impl.h 2006-08-09 21:56:09.000000000 -0500
33436 @@ -0,0 +1,58 @@
33439 + * Copyright (C) James R. Leu 2002
33440 + * jleu@mindspring.com
33442 + * This software is covered under the LGPL, for more
33443 + * info check out http://www.gnu.org/copyleft/lgpl.html
33444 + */
33446 +#ifndef _MPLS_IFMGR_IMPL_H_
33447 +#define _MPLS_IFMGR_IMPL_H_
33449 +#include "mpls_struct.h"
33450 +#include "mpls_handle_type.h"
33453 + * in: handle,cfg
33454 + * return: mpls_ifmgr_handle
33455 + */
33456 +extern mpls_ifmgr_handle mpls_ifmgr_open(const mpls_instance_handle handle,
33457 + const mpls_cfg_handle cfg);
33460 + * in: handle
33461 + */
33462 +extern void mpls_ifmgr_close(const mpls_ifmgr_handle handle);
33465 + * in: handle,iff,mtu
33466 + * out: mtu
33467 + * return: mpls_return_enum
33468 + */
33469 +extern mpls_return_enum mpls_ifmgr_get_mtu(const mpls_ifmgr_handle,
33470 + const mpls_if_handle iff, int *mtu);
33473 + * in: handle,iff,name,size
33474 + * out: name
33475 + * return: mpls_return_enum
33476 + */
33477 +extern mpls_return_enum mpls_ifmgr_get_name(const mpls_ifmgr_handle,
33478 + const mpls_if_handle iff, char *name, int len);
33481 + * in: handle, handle, addr
33482 + * return: mpls_return_enum
33483 + */
33484 +extern mpls_return_enum mpls_ifmgr_getfirst_address(const mpls_ifmgr_handle,
33485 + mpls_if_handle*, mpls_inet_addr*);
33488 + * in: handle, handle, addr
33489 + * return: mpls_return_enum
33490 + */
33491 +extern mpls_return_enum mpls_ifmgr_getnext_address(const mpls_ifmgr_handle,
33492 + mpls_if_handle*, mpls_inet_addr*);
33494 +#endif
33495 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_list.h quagga-mpls/ldpd/mpls_list.h
33496 --- quagga/ldpd/mpls_list.h 1969-12-31 18:00:00.000000000 -0600
33497 +++ quagga-mpls/ldpd/mpls_list.h 2006-08-09 21:56:10.000000000 -0500
33498 @@ -0,0 +1,309 @@
33501 + * Copyright (C) James R. Leu 2002
33502 + * jleu@mindspring.com
33504 + * This software is covered under the LGPL, for more
33505 + * info check out http://www.gnu.org/copyleft/lgpl.html
33506 + */
33508 +#ifndef _MPLS_LIST_H_
33509 +#define _MPLS_LIST_H_
33511 +#include "mpls_mm_impl.h"
33513 +/* Endo list, the prev,next ptrs are part of the element in the list */
33514 +/* No addition memory allocations are done when inserting into the list */
33516 +#define MPLS_LIST_ROOT(name,type) \
33517 +struct name { \
33518 + struct type *llh_first; \
33519 + struct type *llh_last; \
33520 + int count; \
33523 +#define MPLS_LIST_ELEM(type) \
33524 +struct { \
33525 + struct type *lle_next; \
33526 + struct type *lle_prev; \
33529 +#define MPLS_LIST_REMOVE(head, elm, field) { \
33530 + if((elm)->field.lle_next == (void *)(head)) \
33531 + (head)->llh_last = (elm)->field.lle_prev; \
33532 + else \
33533 + (elm)->field.lle_next->field.lle_prev = (elm)->field.lle_prev; \
33534 + if((elm)->field.lle_prev == (void *)(head)) \
33535 + (head)->llh_first = (elm)->field.lle_next; \
33536 + else \
33537 + (elm)->field.lle_prev->field.lle_next = (elm)->field.lle_next; \
33538 + (head)->count--; \
33541 +#define MPLS_LIST_INSERT_BEFORE(head,listelm,elm,field) { \
33542 + (elm)->field.lle_next = (listelm); \
33543 + (elm)->field.lle_prev = (listelm)->field.lle_prev; \
33544 + if((listelm)->field.lle_prev == (void *)(head)) \
33545 + (head)->llh_first = (elm); \
33546 + else \
33547 + (listelm)->field.lle_prev->field.lle_next = (elm); \
33548 + (listelm)->field.lle_prev = (elm); \
33549 + (head)->count++; \
33552 +#define MPLS_LIST_INIT(head,type) { \
33553 + (head)->llh_first = (struct type *)(head); \
33554 + (head)->llh_last = (struct type *)(head); \
33555 + (head)->count = 0; \
33558 +#define MPLS_LIST_IN_LIST(elm,field) ((elm)->field.lle_next && (elm)->field.lle_prev)
33560 +#define MPLS_LIST_ADD_HEAD(head, elm, field, type) { \
33561 + (elm)->field.lle_next = (head)->llh_first; \
33562 + (elm)->field.lle_prev = (struct type *)(head); \
33563 + if ((head)->llh_last == (struct type *)(head)) \
33564 + (head)->llh_last = (elm); \
33565 + else \
33566 + (head)->llh_first->field.lle_prev = (elm); \
33567 + (head)->llh_first = (elm); \
33568 + (head)->count++; \
33571 +#define MPLS_LIST_ADD_TAIL(head, elm, field, type) { \
33572 + (elm)->field.lle_next = (struct type *)(head); \
33573 + (elm)->field.lle_prev = (head)->llh_last; \
33574 + if ((head)->llh_first == (struct type *)(head)) \
33575 + (head)->llh_first = (elm); \
33576 + else \
33577 + (head)->llh_last->field.lle_next = (elm); \
33578 + (head)->llh_last = (elm); \
33579 + (head)->count++; \
33582 +#define MPLS_LIST_REMOVE_TAIL(root,elem,field) { \
33583 + (elem) = (root)->llh_last; \
33584 + if((elem) && (elem) != (void*)(root)) { \
33585 + MPLS_LIST_REMOVE(root,elem,field); \
33586 + } else { \
33587 + (elem) = NULL; \
33588 + } \
33589 + (root)->count--; \
33592 +#define MPLS_LIST_REMOVE_HEAD(root,elem,field) { \
33593 + (elem) = (root)->llh_first; \
33594 + if((elem) && (elem) != (void*)(root)) { \
33595 + MPLS_LIST_REMOVE(root,elem,field); \
33596 + } else { \
33597 + (elem) = NULL; \
33598 + } \
33599 + (root)->count--; \
33602 +#define MPLS_LIST_ELEM_INIT(elem,field) { \
33603 + (elem)->field.lle_next = NULL; \
33604 + (elem)->field.lle_prev = NULL; \
33607 +#define MPLS_LIST_HEAD(root) (((root)->llh_first == (void*)(root))?(NULL):((root)->llh_first))
33608 +#define MPLS_LIST_NEXT(root,elem,field) ((((elem)->field.lle_next) == (void*)(root))?(NULL):((elem)->field.lle_next))
33609 +#define MPLS_LIST_PREV(root,elem,field) ((((elem)->field.lle_prev) == (void*)(root))?(NULL):((elem)->field.lle_prev))
33610 +#define MPLS_LIST_TAIL(root) (((root)->llh_last == (void*)(root))?(NULL):((root)->llh_last))
33612 +#define MPLS_LIST_EMPTY(root) ((root)->count ? MPLS_BOOL_FALSE : MPLS_BOOL_TRUE)
33614 +/* non Endo list, the list node has the next,prev pointers and a pointer to */
33615 +/* the data being stored, a memory allocation has to occur for each insert */
33617 +typedef struct mpls_link_list_node {
33618 + struct mpls_link_list_node *next;
33619 + struct mpls_link_list_node *prev;
33620 + void *data;
33621 +} mpls_link_list_node;
33623 +typedef struct mpls_link_list {
33624 + struct mpls_link_list_node *head;
33625 + struct mpls_link_list_node *tail;
33626 + int count;
33627 +} mpls_link_list;
33629 +#define mpls_link_list_head(X) ((X)->head)
33630 +#define mpls_link_list_head_data(X) ((X)->head ? (X)->head->data : NULL)
33631 +#define mpls_link_list_tail(X) ((X)->tail)
33632 +#define mpls_link_list_tail_data(X) ((X)->tail ? (X)->tail->data : NULL)
33633 +#define mpls_link_list_count(X) ((X)->count)
33634 +#define mpls_link_list_isempty(X) ((X)->head == NULL && (X)->tail == NULL)
33636 +#define MPLS_LINK_LIST_LOOP(LIST,DATA,NODE) \
33637 + for ((NODE) = (LIST)->head; (NODE); (NODE) = (NODE)->next) \
33638 + if (((DATA) = (NODE)->data) != NULL)
33640 +static inline void mpls_link_list_init(struct mpls_link_list *list) {
33641 + memset(list, 0, sizeof(*list));
33644 +static inline struct mpls_link_list *mpls_link_list_create() {
33645 + struct mpls_link_list *list;
33647 + if ((list = mpls_malloc(sizeof(*list)))) {
33648 + mpls_link_list_init(list);
33650 + return list;
33653 +static inline void mpls_link_list_delete(struct mpls_link_list *list) {
33654 + mpls_free(list);
33657 +static inline struct mpls_link_list_node *mpls_link_list_node_create(void *data)
33659 + struct mpls_link_list_node *node;
33661 + if ((node = mpls_malloc(sizeof(*node)))) {
33662 + memset(node, 0, sizeof(*node));
33663 + node->data = data;
33665 + return node;
33668 +static inline void mpls_link_list_node_delete(struct mpls_link_list_node *node)
33670 + mpls_free(node);
33673 +static inline void mpls_link_list_add_node_head(struct mpls_link_list *list,
33674 + struct mpls_link_list_node *node) {
33675 + node->next = list->head;
33677 + if (list->tail == NULL) {
33678 + list->tail = node;
33679 + } else {
33680 + list->head->prev = node;
33681 + node->next = list->head;
33683 + list->head = node;
33684 + list->count++;
33687 +static inline mpls_return_enum mpls_link_list_add_head(
33688 + struct mpls_link_list *list, void * data) {
33689 + struct mpls_link_list_node *node;
33691 + if ((node = mpls_link_list_node_create(data))) {
33692 + mpls_link_list_add_node_head(list,node);
33693 + return MPLS_SUCCESS;
33695 + return MPLS_FATAL;
33698 +static inline void mpls_link_list_add_node_tail(
33699 + struct mpls_link_list *list, struct mpls_link_list_node *node) {
33700 + node->prev = list->tail;
33702 + if (list->head == NULL) {
33703 + list->head = node;
33704 + } else {
33705 + node->prev = list->tail;
33706 + list->tail->next = node;
33708 + list->tail = node;
33709 + list->count++;
33712 +static inline mpls_return_enum mpls_link_list_add_tail(
33713 + struct mpls_link_list *list, void *data) {
33714 + struct mpls_link_list_node *node;
33716 + if ((node = mpls_link_list_node_create(data))) {
33717 + mpls_link_list_add_node_tail(list, node);
33718 + return MPLS_SUCCESS;
33720 + return MPLS_FATAL;
33723 +static inline void mpls_link_list_add_node_before(struct mpls_link_list *list,
33724 + struct mpls_link_list_node *ptr, struct mpls_link_list_node *node) {
33725 + if (list->head == ptr) {
33726 + node->next = ptr;
33727 + ptr->prev = node;
33728 + list->head = node;
33729 + } else {
33730 + node->prev = ptr->prev;
33731 + node->next = ptr;
33732 + ptr->prev->next = node;
33733 + ptr->prev = node;
33735 + list->count++;
33738 +static inline mpls_return_enum mpls_link_list_add_data_before(
33739 + struct mpls_link_list *list, struct mpls_link_list_node *ptr, void *data) {
33740 + struct mpls_link_list_node *node;
33742 + if ((node = mpls_link_list_node_create(data))) {
33743 + mpls_link_list_add_node_before(list,ptr,node);
33744 + return MPLS_SUCCESS;
33746 + return MPLS_FATAL;
33749 +static inline void mpls_link_list_add_node_after(struct mpls_link_list *list,
33750 + struct mpls_link_list_node *ptr, struct mpls_link_list_node *node) {
33751 + if (list->tail == ptr) {
33752 + ptr->next = node;
33753 + node->prev = ptr;
33754 + list->tail = node;
33755 + } else {
33756 + node->prev = ptr;
33757 + node->next = ptr->next;
33758 + ptr->next = node;
33759 + ptr->next->prev = node;
33761 + list->count++;
33764 +static inline mpls_return_enum mpls_link_list_add_data_after(
33765 + struct mpls_link_list *list, struct mpls_link_list_node *ptr, void *data) {
33766 + struct mpls_link_list_node *node;
33768 + if ((node = mpls_link_list_node_create(data))) {
33769 + mpls_link_list_add_node_after(list, ptr, node);
33770 + return MPLS_SUCCESS;
33772 + return MPLS_FATAL;
33775 +static inline void mpls_link_list_remove_node(struct mpls_link_list *list,
33776 + struct mpls_link_list_node *node) {
33778 + if (node->prev) {
33779 + node->prev->next = node->next;
33780 + } else {
33781 + list->head = node->next;
33784 + if (node->next) {
33785 + node->next->prev = node->prev;
33786 + } else {
33787 + list->tail = node->prev;
33790 + list->count--;
33793 +static inline void mpls_link_list_remove_data(struct mpls_link_list* list,
33794 + void *val)
33796 + struct mpls_link_list_node *node;
33798 + for (node = list->head; node; node = node->next) {
33799 + if (node->data == val) {
33800 + mpls_link_list_remove_node(list,node);
33801 + mpls_link_list_node_delete(node);
33802 + break;
33807 +#endif
33808 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_lock_impl.h quagga-mpls/ldpd/mpls_lock_impl.h
33809 --- quagga/ldpd/mpls_lock_impl.h 1969-12-31 18:00:00.000000000 -0600
33810 +++ quagga-mpls/ldpd/mpls_lock_impl.h 2006-08-09 21:56:09.000000000 -0500
33811 @@ -0,0 +1,36 @@
33814 + * Copyright (C) James R. Leu 2002
33815 + * jleu@mindspring.com
33817 + * This software is covered under the LGPL, for more
33818 + * info check out http://www.gnu.org/copyleft/lgpl.html
33819 + */
33821 +#ifndef _MPLS_LOCK_IMPL_H_
33822 +#define _MPLS_LOCK_IMPL_H_
33824 +#include "mpls_struct.h"
33827 + * in: key
33828 + * return: mpls_lock_handle
33829 + */
33830 +extern mpls_lock_handle mpls_lock_create(const mpls_lock_key_type key);
33833 + * in: handle
33834 + */
33835 +extern void mpls_lock_get(mpls_lock_handle handle);
33838 + * in: handle
33839 + */
33840 +extern void mpls_lock_release(mpls_lock_handle handle);
33843 + * in: handle
33844 + */
33845 +extern void mpls_lock_delete(mpls_lock_handle handle);
33847 +#endif
33848 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_mm_impl.h quagga-mpls/ldpd/mpls_mm_impl.h
33849 --- quagga/ldpd/mpls_mm_impl.h 1969-12-31 18:00:00.000000000 -0600
33850 +++ quagga-mpls/ldpd/mpls_mm_impl.h 2006-08-09 21:56:09.000000000 -0500
33851 @@ -0,0 +1,26 @@
33854 + * Copyright (C) James R. Leu 2002
33855 + * jleu@mindspring.com
33857 + * This software is covered under the LGPL, for more
33858 + * info check out http://www.gnu.org/copyleft/lgpl.html
33859 + */
33861 +#ifndef _MPLS_MM_IMPL_H_
33862 +#define _MPLS_MM_IMPL_H_
33864 +#include "mpls_struct.h"
33867 + * in: size
33868 + * return: void*
33869 + */
33870 +extern void *mpls_malloc(const mpls_size_type size);
33873 + * in: mem
33874 + */
33875 +extern void mpls_free(void *mem);
33877 +#endif
33878 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_mpls_impl.h quagga-mpls/ldpd/mpls_mpls_impl.h
33879 --- quagga/ldpd/mpls_mpls_impl.h 1969-12-31 18:00:00.000000000 -0600
33880 +++ quagga-mpls/ldpd/mpls_mpls_impl.h 2006-08-09 21:56:09.000000000 -0500
33881 @@ -0,0 +1,82 @@
33884 + * Copyright (C) James R. Leu 2002
33885 + * jleu@mindspring.com
33887 + * This software is covered under the LGPL, for more
33888 + * info check out http://www.gnu.org/copyleft/lgpl.html
33889 + */
33891 +#ifndef _MPLS_MPLS_IMPL_H_
33892 +#define _MPLS_MPLS_IMPL_H_
33894 +#include "mpls_struct.h"
33896 +struct ldp_inlabel;
33897 +struct ldp_outlabel;
33900 + * in: handle
33901 + * return: mpls_mpls_handle
33902 + */
33903 +extern mpls_mpls_handle mpls_mpls_open(mpls_instance_handle handle);
33906 + * in: handle
33907 + */
33908 +extern void mpls_mpls_close(mpls_mpls_handle handle);
33911 + * in: handle, o
33912 + * return: mpls_return_enum
33913 + */
33914 +extern mpls_return_enum mpls_mpls_outsegment_add(mpls_mpls_handle handle,
33915 + struct mpls_outsegment * o);
33918 + * in: handle, o
33919 + */
33920 +extern void mpls_mpls_outsegment_del(mpls_mpls_handle handle, struct mpls_outsegment * o);
33923 + * in: handle, i
33924 + * return: mpls_return_enum
33925 + */
33926 +extern mpls_return_enum mpls_mpls_insegment_add(mpls_mpls_handle handle,
33927 + struct mpls_insegment * i);
33930 + * in: handle, i
33931 + */
33932 +extern void mpls_mpls_insegment_del(mpls_mpls_handle handle, struct mpls_insegment * i);
33935 + * in: handle, i, o
33936 + * return: mpls_return_enum
33937 + */
33938 +extern mpls_return_enum mpls_mpls_xconnect_add(mpls_mpls_handle handle,
33939 + struct mpls_insegment * i, struct mpls_outsegment * o);
33942 + * in: handle, i, o
33943 + */
33944 +extern void mpls_mpls_xconnect_del(mpls_mpls_handle handle,
33945 + struct mpls_insegment * i, struct mpls_outsegment * o);
33948 + * in: handle, f, o
33949 + * return: mpls_return_enum
33950 + */
33951 +extern mpls_return_enum mpls_mpls_fec2out_add(mpls_mpls_handle handle,
33952 + mpls_fec * f, struct mpls_outsegment * o);
33955 + * in: handle, f, o
33956 + */
33957 +extern void mpls_mpls_fec2out_del(mpls_mpls_handle handle,
33958 + mpls_fec * f, struct mpls_outsegment * o);
33960 +extern mpls_return_enum mpls_mpls_get_label_space_range(mpls_mpls_handle handle,
33961 + mpls_range *range);
33963 +#endif
33964 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_policy_impl.h quagga-mpls/ldpd/mpls_policy_impl.h
33965 --- quagga/ldpd/mpls_policy_impl.h 1969-12-31 18:00:00.000000000 -0600
33966 +++ quagga-mpls/ldpd/mpls_policy_impl.h 2006-08-09 21:56:09.000000000 -0500
33967 @@ -0,0 +1,24 @@
33970 + * Copyright (C) James R. Leu 2002
33971 + * jleu@mindspring.com
33973 + * This software is covered under the LGPL, for more
33974 + * info check out http://www.gnu.org/copyleft/lgpl.html
33975 + */
33977 +#ifndef _MPLS_POLICY_IMPL_H_
33978 +#define _MPLS_POLICY_IMPL_H_
33980 +extern mpls_bool mpls_policy_import_check(mpls_instance_handle handle,
33981 + mpls_fec * f, mpls_nexthop * nh);
33982 +extern mpls_bool mpls_policy_ingress_check(mpls_instance_handle handle,
33983 + mpls_fec * f, mpls_nexthop * nh);
33984 +extern mpls_bool mpls_policy_egress_check(mpls_instance_handle handle,
33985 + mpls_fec * p, mpls_nexthop *nh);
33986 +extern mpls_bool mpls_policy_export_check(mpls_instance_handle handle,
33987 + mpls_fec * p, mpls_nexthop * nh);
33988 +extern mpls_bool mpls_policy_address_export_check(mpls_instance_handle handle,
33989 + mpls_inet_addr * addr);
33991 +#endif
33992 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_refcnt.h quagga-mpls/ldpd/mpls_refcnt.h
33993 --- quagga/ldpd/mpls_refcnt.h 1969-12-31 18:00:00.000000000 -0600
33994 +++ quagga-mpls/ldpd/mpls_refcnt.h 2006-08-09 21:56:09.000000000 -0500
33995 @@ -0,0 +1,69 @@
33998 + * Copyright (C) James R. Leu 2002
33999 + * jleu@mindspring.com
34001 + * This software is covered under the LGPL, for more
34002 + * info check out http://www.gnu.org/copyleft/lgpl.html
34003 + */
34005 +#ifndef _MPLS_REFCNT_H_
34006 +#define _MPLS_REFCNT_H_
34008 +#include "mpls_assert.h"
34010 +#define MPLS_REFCNT_FIELD uint32_t _refcnt
34012 +#define MPLS_REFCNT_VALUE(obj) (obj)?((obj)->_refcnt):(-1)
34014 +#define MPLS_REFCNT_INIT(obj,count) { \
34015 + (obj)->_refcnt = count; \
34018 +#define MPLS_REFCNT_HOLD(obj) { \
34019 + if((obj) != NULL) { \
34020 + (obj)->_refcnt++; \
34021 + } \
34024 +#define MPLS_REFCNT_RELEASE(obj,dstry) { \
34025 + if((obj) != NULL) { \
34026 + (obj)->_refcnt--; \
34027 + if((obj)->_refcnt <= 0) { \
34028 + dstry(obj); \
34029 + obj = NULL; \
34030 + } \
34031 + } \
34034 +#define MPLS_REFCNT_RELEASE2(global,obj,dstry) { \
34035 + if((obj) != NULL) { \
34036 + (obj)->_refcnt--; \
34037 + if((obj)->_refcnt <= 0) { \
34038 + dstry(global,obj); \
34039 + obj = NULL; \
34040 + } \
34041 + } \
34044 +#define MPLS_REFCNT_ASSERT(obj,count) { \
34045 + if((obj) != NULL) { \
34046 + MPLS_ASSERT((obj)->_refcnt == count); \
34047 + } \
34050 +#define MPLS_REFCNT_PTR_TYPE uint32_t*
34051 +#define MPLS_REFCNT_PTR(obj) (((obj) != NULL)?(&((obj)->_refcnt)):(NULL))
34053 +#define MPLS_REFCNT_PTR_HOLD(ptr) { \
34054 + if((ptr) != NULL) { \
34055 + ((*(ptr))++); \
34056 + } \
34058 +#define MPLS_REFCNT_PTR_RELEASE(ptr) { \
34059 + if((ptr) != NULL) { \
34060 + ((*(ptr))--); \
34061 + } \
34064 +#endif
34065 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_socket_impl.h quagga-mpls/ldpd/mpls_socket_impl.h
34066 --- quagga/ldpd/mpls_socket_impl.h 1969-12-31 18:00:00.000000000 -0600
34067 +++ quagga-mpls/ldpd/mpls_socket_impl.h 2006-11-21 20:33:16.000000000 -0600
34068 @@ -0,0 +1,195 @@
34071 + * Copyright (C) James R. Leu 2000
34072 + * jleu@mindspring.com
34074 + * This software is covered under the LGPL, for more
34075 + * info check out http://www.gnu.org/copyleft/lgpl.html
34076 + */
34078 +#ifndef _MPLS_SOCKET_IMPL_H_
34079 +#define _MPLS_SOCKET_IMPL_H_
34081 +#include "ldp_struct.h"
34082 +#include "mpls_struct.h"
34085 + * in: handle
34086 + * return: mpls_socket_mgr_handle
34087 + */
34088 +extern mpls_socket_mgr_handle mpls_socket_mgr_open(const mpls_instance_handle
34089 + handle);
34092 + * in: handle
34093 + */
34094 +extern void mpls_socket_mgr_close(const mpls_socket_mgr_handle handle);
34097 + * in: handle
34098 + * return: mpls_socket_handle
34099 + */
34100 +extern mpls_socket_handle mpls_socket_create_tcp(const mpls_socket_mgr_handle
34101 + handle);
34104 + * in: handle
34105 + * return: mpls_socket_handle
34106 + */
34107 +extern mpls_socket_handle mpls_socket_create_udp(const mpls_socket_mgr_handle
34108 + handle);
34111 + * in: handle
34112 + * return: mpls_socket_handle
34113 + */
34114 +extern mpls_socket_handle mpls_socket_create_raw(const mpls_socket_mgr_handle
34115 + handle, int proto);
34118 + * in: handle,socket,from
34119 + * out: from
34120 + * return: mpls_socket_handle
34121 + */
34122 +extern mpls_socket_handle mpls_socket_tcp_accept(const mpls_socket_mgr_handle
34123 + handle, const mpls_socket_handle socket, mpls_dest * from);
34126 + * in: handle,socket
34127 + */
34128 +extern void mpls_socket_close(const mpls_socket_mgr_handle handle,
34129 + mpls_socket_handle socket);
34132 + * in: handle,socket,local
34133 + * return: mpls_return_enum
34134 + */
34135 +extern mpls_return_enum mpls_socket_bind(const mpls_socket_mgr_handle handle,
34136 + mpls_socket_handle socket, const mpls_dest * local);
34139 + * in: handle, socket, flag
34140 + * return: mpls_return_enum
34141 + */
34142 +extern mpls_return_enum mpls_socket_options(const mpls_socket_mgr_handle handle,
34143 + mpls_socket_handle socket, const uint32_t flag);
34146 + * in: handle, socket, depth
34147 + * return: mpls_return_enum
34148 + */
34149 +extern mpls_return_enum mpls_socket_tcp_listen(const mpls_socket_mgr_handle handle,
34150 + mpls_socket_handle socket, const int depth);
34153 + * in: handle, socket, to
34154 + * return: mpls_return_enum
34155 + */
34156 +extern mpls_return_enum mpls_socket_tcp_connect(const mpls_socket_mgr_handle
34157 + handle, mpls_socket_handle socket, const mpls_dest * to);
34160 + * in: handle, socket
34161 + * return: int
34162 + */
34163 +extern int mpls_socket_get_errno(const mpls_socket_mgr_handle handle,
34164 + mpls_socket_handle socket);
34167 + * in: handle, socket
34168 + * return: mpls_return_enum
34169 + */
34170 +extern mpls_return_enum mpls_socket_connect_status(const mpls_socket_mgr_handle
34171 + handle, mpls_socket_handle socket);
34174 + * in: handle, socket, ttl, loop
34175 + * return: mpls_return_enum
34176 + */
34177 +extern mpls_return_enum mpls_socket_multicast_options(const mpls_socket_mgr_handle handle, mpls_socket_handle socket, const int ttl, const int loop);
34180 + * in: handle, socket, iff
34181 + * return: mpls_return_enum
34182 + */
34183 +extern mpls_return_enum mpls_socket_multicast_if_tx(const mpls_socket_mgr_handle
34184 + handle, mpls_socket_handle socket, const ldp_if * iff);
34187 + * in: handle, socket, iff, mult
34188 + * return: mpls_return_enum
34189 + */
34190 +extern mpls_return_enum mpls_socket_multicast_if_join(const mpls_socket_mgr_handle handle, mpls_socket_handle socket, const ldp_if * iff,
34191 + const mpls_inet_addr * mult);
34194 + * in: handle, socket, iff, mult
34195 + */
34196 +extern void mpls_socket_multicast_if_drop(const mpls_socket_mgr_handle handle,
34197 + mpls_socket_handle socket, const ldp_if * iff, const mpls_inet_addr * mult);
34200 + * in: handle, socket, object, type
34201 + * return: mpls_return_enum
34202 + */
34203 +extern mpls_return_enum mpls_socket_readlist_add(const mpls_socket_mgr_handle
34204 + handle, mpls_socket_handle socket, void *object, const mpls_socket_enum type);
34207 + * in: handle, socket
34208 + */
34209 +extern void mpls_socket_readlist_del(const mpls_socket_mgr_handle handle,
34210 + mpls_socket_handle socket);
34213 + * in: handle, socket, object, type
34214 + * return: mpls_return_enum
34215 + */
34216 +extern mpls_return_enum mpls_socket_writelist_add(const mpls_socket_mgr_handle
34217 + handle, mpls_socket_handle socket, void *object, const mpls_socket_enum type);
34220 + * in: handle, socket
34221 + */
34222 +extern void mpls_socket_writelist_del(const mpls_socket_mgr_handle handle,
34223 + mpls_socket_handle socket);
34226 + * in: handle, o
34227 + * return: int
34228 + */
34229 +extern int mpls_socket_tcp_read(const mpls_socket_mgr_handle handle,
34230 + mpls_socket_handle socket, uint8_t * buffer, const int size);
34233 + * in: handle, o
34234 + * return: int
34235 + */
34236 +extern int mpls_socket_tcp_write(const mpls_socket_mgr_handle handle,
34237 + mpls_socket_handle socket, uint8_t * buffer, const int size);
34240 + * in: handle, o
34241 + * return: int
34242 + */
34243 +extern int mpls_socket_udp_sendto(const mpls_socket_mgr_handle handle,
34244 + mpls_socket_handle socket, uint8_t * buffer,
34246 + const int size, const mpls_dest * to);
34249 + * in: handle, o
34250 + * return: int
34251 + */
34252 +extern int mpls_socket_udp_recvfrom(const mpls_socket_mgr_handle handle,
34253 + mpls_socket_handle socket, uint8_t * buffer, const int size, mpls_dest * from);
34255 +extern mpls_return_enum
34256 +mpls_socket_get_local_name(const mpls_socket_mgr_handle handle,
34257 + mpls_socket_handle socket, mpls_dest *name);
34259 +extern mpls_return_enum
34260 +mpls_socket_get_remote_name(const mpls_socket_mgr_handle handle,
34261 + mpls_socket_handle socket, mpls_dest *name);
34263 +#endif
34264 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_struct.h quagga-mpls/ldpd/mpls_struct.h
34265 --- quagga/ldpd/mpls_struct.h 1969-12-31 18:00:00.000000000 -0600
34266 +++ quagga-mpls/ldpd/mpls_struct.h 2006-11-08 20:39:36.000000000 -0600
34267 @@ -0,0 +1,242 @@
34270 + * Copyright (C) James R. Leu 2002
34271 + * jleu@mindspring.com
34273 + * This software is covered under the LGPL, for more
34274 + * info check out http://www.gnu.org/copyleft/lgpl.html
34275 + */
34277 +#ifndef _MPLS_STRUCT_H_
34278 +#define _MPLS_STRUCT_H_
34280 +#define MPLS_MAX_IF_NAME 16
34281 +#define MPLS_MAX_LABELSTACK 4
34283 +#include "mpls_handle_type.h"
34284 +#include "mpls_bitfield.h"
34286 +typedef enum {
34287 + MPLS_SUCCESS = 1,
34288 + MPLS_FAILURE,
34289 + MPLS_FATAL,
34290 + MPLS_CLOSED,
34291 + MPLS_NON_BLOCKING,
34292 + MPLS_END_OF_LIST,
34293 + MPLS_NO_ROUTE,
34294 +} mpls_return_enum;
34296 +typedef enum {
34297 + MPLS_UPDATE_ADD,
34298 + MPLS_UPDATE_DEL,
34299 + MPLS_UPDATE_MODIFY
34300 +} mpls_update_enum;
34302 +typedef enum {
34303 + MPLS_OPER_UP = 1,
34304 + MPLS_OPER_DOWN,
34305 +} mpls_oper_state_enum;
34307 +typedef enum {
34308 + MPLS_TIMER_ONESHOT = 1,
34309 + MPLS_TIMER_REOCCURRING,
34310 +} mpls_timer_type_enum;
34312 +typedef enum {
34313 + MPLS_UNIT_MICRO = 1,
34314 + MPLS_UNIT_SEC,
34315 + MPLS_UNIT_MIN,
34316 + MPLS_UNIT_HOUR
34317 +} mpls_time_unit_enum;
34319 +typedef enum {
34320 + MPLS_ADMIN_ENABLE = 1,
34321 + MPLS_ADMIN_DISABLE
34322 +} mpls_admin_state_enum;
34324 +typedef enum {
34325 + MPLS_LABEL_RANGE_GENERIC = 1,
34326 + MPLS_LABEL_RANGE_ATM_VP,
34327 + MPLS_LABEL_RANGE_ATM_VC,
34328 + MPLS_LABEL_RANGE_ATM_VP_VC,
34329 + MPLS_LABEL_RANGE_FR_10,
34330 + MPLS_LABEL_RANGE_FR_24
34331 +} mpls_label_range_type;
34333 +typedef enum {
34334 + MPLS_LABEL_TYPE_NONE,
34335 + MPLS_LABEL_TYPE_GENERIC,
34336 + MPLS_LABEL_TYPE_ATM,
34337 + MPLS_LABEL_TYPE_FR
34338 +} mpls_label_type;
34340 +typedef enum {
34341 + MPLS_BOOL_FALSE = 0,
34342 + MPLS_BOOL_TRUE = 1
34343 +} mpls_bool;
34345 +typedef enum {
34346 + MPLS_SOCKET_UDP_DATA = 1,
34347 + MPLS_SOCKET_TCP_LISTEN,
34348 + MPLS_SOCKET_TCP_CONNECT,
34349 + MPLS_SOCKET_TCP_DATA,
34350 + MPLS_SOCKET_ROUTE_UPDATE,
34351 +} mpls_socket_enum;
34353 +typedef enum {
34354 + MPLS_SOCKOP_NONBLOCK = 0x1,
34355 + MPLS_SOCKOP_REUSE = 0x2,
34356 + MPLS_SOCKOP_ROUTERALERT = 0x4,
34357 + MPLS_SOCKOP_HDRINCL = 0x8
34358 +} mpls_socket_option_type;
34360 +typedef enum {
34361 + MPLS_TRACE_STATE_SEND,
34362 + MPLS_TRACE_STATE_RECV,
34363 + MPLS_TRACE_STATE_ALL
34364 +} mpls_trace_states;
34366 +typedef enum {
34367 + MPLS_OWNER_LDP,
34368 + MPLS_OWNER_CRLDP,
34369 + MPLS_OWNER_STATIC,
34370 + MPLS_OWNER_RSVP_TE
34371 +} mpls_owners_enum;
34373 +/* this structure is slurped from GNU header files */
34374 +typedef struct mpls_iphdr {
34375 + BITFIELDS_ASCENDING_2(unsigned int ihl:4,
34376 + unsigned int version:4);
34377 + u_int8_t tos;
34378 + u_int16_t tot_len;
34379 + u_int16_t id;
34380 + u_int16_t frag_off;
34381 + u_int8_t ttl;
34382 + u_int8_t protocol;
34383 + u_int16_t check;
34384 + u_int32_t saddr;
34385 + u_int32_t daddr;
34386 + /*The options start here. */
34387 +} mpls_iphdr;
34389 +typedef struct mpls_label_struct {
34390 + mpls_label_type type;
34391 + union {
34392 + int gen;
34393 + struct {
34394 + int vpi;
34395 + int vci;
34396 + } atm;
34397 + struct {
34398 + int len;
34399 + int dlci;
34400 + } fr;
34401 + } u;
34402 +} mpls_label_struct;
34404 +typedef enum mpls_family_enum {
34405 + MPLS_FAMILY_NONE,
34406 + MPLS_FAMILY_IPV4,
34407 + MPLS_FAMILY_IPV6,
34408 +} mpls_family_enum;
34410 +typedef struct mpls_inet_addr {
34411 + enum mpls_family_enum type;
34412 + union {
34413 + uint8_t ipv6[16];
34414 + uint32_t ipv4;
34415 + } u;
34416 +} mpls_inet_addr;
34418 +typedef struct mpls_dest {
34419 + struct mpls_inet_addr addr;
34420 + uint16_t port;
34421 + mpls_if_handle if_handle;
34422 +} mpls_dest;
34424 +typedef struct mpls_range {
34425 + int label_space;
34426 + mpls_label_range_type type;
34427 + struct mpls_label_struct min, max;
34428 +} mpls_range;
34430 +typedef enum mpls_nexthop_enum {
34431 + MPLS_NH_NONE = 0x0,
34432 + MPLS_NH_IP = 0x1,
34433 + MPLS_NH_IF = 0x2,
34434 + MPLS_NH_OUTSEGMENT = 0x4
34435 +} mpls_nexthop_enum;
34437 +typedef enum mpls_fec_enum {
34438 + MPLS_FEC_NONE,
34439 + MPLS_FEC_PREFIX,
34440 + MPLS_FEC_HOST,
34441 + MPLS_FEC_L2CC,
34442 +} mpls_fec_enum;
34444 +struct mpls_fec;
34446 +typedef struct mpls_nexthop {
34447 + short distance;
34448 + short metric;
34449 + mpls_bool attached;
34451 + unsigned char type;
34452 + struct mpls_inet_addr ip;
34453 + mpls_if_handle if_handle;
34454 + mpls_outsegment_handle outsegment_handle;
34456 + /* only used during gets */
34457 + uint32_t index;
34458 +} mpls_nexthop;
34460 +typedef struct mpls_fec {
34461 + enum mpls_fec_enum type;
34462 + union {
34463 + struct {
34464 + struct mpls_inet_addr network;
34465 + uint8_t length;
34466 + } prefix;
34467 + struct mpls_inet_addr host;
34468 + struct {
34469 + mpls_if_handle interface;
34470 + uint32_t connection_id;
34471 + uint32_t group_id;
34472 + uint8_t type;
34473 + } l2cc;
34474 + } u;
34476 + /* only used during gets */
34477 + mpls_bool is_route;
34478 + uint32_t index;
34479 +} mpls_fec;
34481 +typedef struct mpls_insegment {
34482 + struct mpls_label_struct label;
34483 + uint32_t npop;
34484 + uint32_t labelspace;
34485 + uint16_t family;
34486 + mpls_insegment_handle handle;
34487 + mpls_owners_enum owner;
34488 +} mpls_insegment;
34490 +typedef struct mpls_outsegment {
34491 + struct mpls_label_struct label;
34492 + mpls_bool push_label;
34493 + struct mpls_nexthop nexthop;
34494 + mpls_outsegment_handle handle;
34495 + mpls_owners_enum owner;
34496 +} mpls_outsegment;
34498 +typedef struct mpls_xconnect {
34499 + uint32_t lspid;
34500 + uint8_t stack_size;
34501 + struct mpls_label_struct stack[MPLS_MAX_LABELSTACK];
34502 + mpls_bool is_persistent;
34503 + mpls_xconnect_handle handle;
34504 + mpls_owners_enum owner;
34505 +} mpls_xconnect;
34507 +typedef void *mpls_cfg_handle;
34509 +#endif
34510 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_timer_impl.h quagga-mpls/ldpd/mpls_timer_impl.h
34511 --- quagga/ldpd/mpls_timer_impl.h 1969-12-31 18:00:00.000000000 -0600
34512 +++ quagga-mpls/ldpd/mpls_timer_impl.h 2006-08-09 21:56:09.000000000 -0500
34513 @@ -0,0 +1,61 @@
34516 + * Copyright (C) James R. Leu 2000
34517 + * jleu@mindspring.com
34519 + * This software is covered under the LGPL, for more
34520 + * info check out http://www.gnu.org/copyleft/lgpl.html
34521 + */
34523 +#ifndef _MPLS_TIMER_IMPL_H_
34524 +#define _MPLS_TIMER_IMPL_H_
34526 +#include "mpls_struct.h"
34529 + * in: handle
34530 + * return: mpls_timer_mgr_handle
34531 + */
34532 +extern mpls_timer_mgr_handle mpls_timer_open(mpls_instance_handle handle);
34535 + * in: handle
34536 + */
34537 +extern void mpls_timer_close(mpls_timer_mgr_handle handle);
34540 + * in: handle, unit, duration, object, cfg, callback
34541 + * return: mpls_timer_handle
34542 + */
34543 +extern mpls_timer_handle mpls_timer_create(const mpls_timer_mgr_handle handle,
34544 + const mpls_time_unit_enum unit, const int duration, void *object,
34545 + const mpls_cfg_handle cfg, void (*callback) (mpls_timer_handle timer,
34546 + void *object, mpls_cfg_handle cfg));
34549 + * in: handle, timer
34550 + */
34551 +extern void mpls_timer_delete(const mpls_timer_mgr_handle handle,
34552 + const mpls_timer_handle timer);
34555 + * in: handle, timer, unit, duration, object, cfg, callback
34556 + * out: mpls_return_enum
34557 + */
34558 +extern mpls_return_enum mpls_timer_modify(const mpls_timer_mgr_handle handle,
34559 + const mpls_timer_handle timer, const int duration);
34562 + * in: handle, timer, type
34563 + * return: mpls_return_enum
34564 + */
34565 +extern mpls_return_enum mpls_timer_start(const mpls_timer_mgr_handle handle,
34566 + const mpls_timer_handle timer, const mpls_timer_type_enum type);
34569 + * in: handle, timer
34570 + */
34571 +extern void mpls_timer_stop(const mpls_timer_mgr_handle handle,
34572 + const mpls_timer_handle timer);
34574 +#endif
34575 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_trace.h quagga-mpls/ldpd/mpls_trace.h
34576 --- quagga/ldpd/mpls_trace.h 1969-12-31 18:00:00.000000000 -0600
34577 +++ quagga-mpls/ldpd/mpls_trace.h 2006-09-27 21:48:55.000000000 -0500
34578 @@ -0,0 +1,60 @@
34579 +#ifndef _LDP_TRACE_H_
34580 +#define _LDP_TRACE_H_
34582 +#include <stdio.h>
34583 +#include <log.h>
34584 +#include "ldp_struct.h"
34586 +extern uint32_t ldp_traceflags;
34587 +extern uint8_t trace_buffer[16834];
34588 +extern int trace_buffer_len;
34590 +#if 0
34591 +1 2 3 4 5 6 7 8
34592 + 12345678901234567890123456789012345678901234567890123456789012345678901234567890
34593 +#endif
34594 +#define LDP_TRACE_OUT(handle,args...) { \
34595 + if(trace_buffer_len == 0) { \
34596 + trace_buffer_len += sprintf(trace_buffer,"OUT: " args);\
34597 + } else { \
34598 + trace_buffer_len += sprintf(trace_buffer+trace_buffer_len,args);\
34599 + } \
34600 + if(trace_buffer[strlen(trace_buffer)-1] == '\n') { \
34601 + trace_buffer[strlen(trace_buffer)-1] = '\0'; \
34602 + zlog_debug("%s",trace_buffer); \
34603 + trace_buffer_len = 0; \
34604 + } \
34606 +#define LDP_TRACE_LOG(handle,class,type,args...) { \
34607 + if(type & ldp_traceflags) { \
34608 + LDP_TRACE_OUT(handle,args); \
34609 + } \
34611 +#define LDP_TRACE_PKT(handle,class,type,header,body) { \
34612 + if(type & ldp_traceflags) { \
34613 + header; \
34614 + body; \
34615 + } \
34617 +#define LDP_DUMP_PKT(handle,class,type,func) { \
34618 + if(type & ldp_traceflags) { \
34619 + func; \
34620 + } \
34622 +#define LDP_PRINT(data,args...) { \
34623 + if(ldp_traceflags & LDP_TRACE_FLAG_DEBUG) { \
34624 + zlog_debug("PRT: " args); \
34625 + } \
34627 +#define LDP_ENTER(data,args...) { \
34628 + if(ldp_traceflags & LDP_TRACE_FLAG_DEBUG) { \
34629 + zlog_debug("ENTER: " args); \
34630 + } \
34632 +#define LDP_EXIT(data,args...) { \
34633 + if(ldp_traceflags & LDP_TRACE_FLAG_DEBUG) { \
34634 + zlog_debug("EXIT: " args); \
34635 + } \
34638 +#endif
34639 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_trace_impl.h quagga-mpls/ldpd/mpls_trace_impl.h
34640 --- quagga/ldpd/mpls_trace_impl.h 1969-12-31 18:00:00.000000000 -0600
34641 +++ quagga-mpls/ldpd/mpls_trace_impl.h 2006-08-09 21:56:09.000000000 -0500
34642 @@ -0,0 +1,15 @@
34645 + * Copyright (C) James R. Leu 2002
34646 + * jleu@mindspring.com
34648 + * This software is covered under the LGPL, for more
34649 + * info check out http://www.gnu.org/copyleft/lgpl.html
34650 + */
34652 +#ifndef _MPLS_TRACE_IMPL_H_
34653 +#define _MPLS_TRACE_IMPL_H_
34655 +#include "mpls_trace.h"
34657 +#endif
34658 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ldpd/mpls_tree_impl.h quagga-mpls/ldpd/mpls_tree_impl.h
34659 --- quagga/ldpd/mpls_tree_impl.h 1969-12-31 18:00:00.000000000 -0600
34660 +++ quagga-mpls/ldpd/mpls_tree_impl.h 2006-08-09 21:56:09.000000000 -0500
34661 @@ -0,0 +1,64 @@
34664 + * Copyright (C) James R. Leu 2002
34665 + * jleu@mindspring.com
34667 + * This software is covered under the LGPL, for more
34668 + * info check out http://www.gnu.org/copyleft/lgpl.html
34669 + */
34671 +#ifndef _MPLS_TREE_IMPL_H_
34672 +#define _MPLS_TREE_IMPL_H_
34674 +#include "mpls_struct.h"
34677 + * in: depth
34678 + * return: mpls_tree_handle
34679 + */
34680 +extern mpls_tree_handle mpls_tree_create(const int depth);
34683 + * in: tree
34684 + */
34685 +extern void mpls_tree_delete(const mpls_tree_handle tree);
34688 + * in: tree,key, length, node
34689 + * return: mpls_return_enum
34690 + */
34691 +extern mpls_return_enum mpls_tree_insert(const mpls_tree_handle tree,
34692 + const uint32_t key, const int length, void *node);
34695 + * in: tree, key, length, node
34696 + * return: mpls_return_enum
34697 + */
34698 +extern mpls_return_enum mpls_tree_remove(const mpls_tree_handle tree,
34699 + const uint32_t key, const int length, void **node);
34702 + * in: tree, key, length, nnode, onode
34703 + * return: mpls_return_enum, onode
34704 + */
34705 +extern mpls_return_enum mpls_tree_replace(const mpls_tree_handle tree,
34706 + const uint32_t key, const int length, void *nnode, void **onode);
34709 + * in: tree, key, length, node
34710 + * return: mpls_return_enum
34711 + */
34712 +extern mpls_return_enum mpls_tree_get(const mpls_tree_handle tree,
34713 + const uint32_t key, const int length, void **node);
34716 + * in: tree, key, length, node
34717 + * return: mpls_return_enum
34718 + */
34719 +extern mpls_return_enum mpls_tree_get_longest(const mpls_tree_handle tree,
34720 + const uint32_t key, void **node);
34722 +extern void mpls_tree_dump(const mpls_tree_handle tree,
34723 + ldp_tree_callback callback);
34725 +#endif
34726 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/lib/command.c quagga-mpls/lib/command.c
34727 --- quagga/lib/command.c 2007-04-29 07:40:39.000000000 -0500
34728 +++ quagga-mpls/lib/command.c 2008-02-19 22:55:33.000000000 -0600
34729 @@ -2385,9 +2385,15 @@
34730 vty->node = ENABLE_NODE;
34731 vty_config_unlock (vty);
34732 break;
34733 + case MPLS_LABELSPACE_NODE:
34734 case INTERFACE_NODE:
34735 + case TUNNEL_NODE:
34736 + case MPLS_TUNNEL_NODE:
34737 + case MPLS_TE_TUNNEL_NODE:
34738 + case MPLS_TE_TUNNEL_CONF_NODE:
34739 case ZEBRA_NODE:
34740 case BGP_NODE:
34741 + case LDP_NODE:
34742 case RIP_NODE:
34743 case RIPNG_NODE:
34744 case OSPF_NODE:
34745 @@ -2409,6 +2415,9 @@
34746 case KEYCHAIN_KEY_NODE:
34747 vty->node = KEYCHAIN_NODE;
34748 break;
34749 + case LDP_IF_NODE:
34750 + vty->node = INTERFACE_NODE;
34751 + break;
34752 default:
34753 break;
34755 @@ -2434,10 +2443,17 @@
34756 /* Nothing to do. */
34757 break;
34758 case CONFIG_NODE:
34759 + case MPLS_LABELSPACE_NODE:
34760 case INTERFACE_NODE:
34761 + case TUNNEL_NODE:
34762 + case MPLS_TUNNEL_NODE:
34763 + case MPLS_TE_TUNNEL_NODE:
34764 + case MPLS_TE_TUNNEL_CONF_NODE:
34765 case ZEBRA_NODE:
34766 case RIP_NODE:
34767 case RIPNG_NODE:
34768 + case LDP_NODE:
34769 + case LDP_IF_NODE:
34770 case BGP_NODE:
34771 case BGP_VPNV4_NODE:
34772 case BGP_IPV4_NODE:
34773 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/lib/command.h quagga-mpls/lib/command.h
34774 --- quagga/lib/command.h 2007-05-02 10:28:32.000000000 -0500
34775 +++ quagga-mpls/lib/command.h 2008-02-19 22:55:33.000000000 -0600
34776 @@ -72,11 +72,18 @@
34777 AAA_NODE, /* AAA node. */
34778 KEYCHAIN_NODE, /* Key-chain node. */
34779 KEYCHAIN_KEY_NODE, /* Key-chain key node. */
34780 + MPLS_LABELSPACE_NODE, /* MPLS Labelspace node. */
34781 INTERFACE_NODE, /* Interface mode node. */
34782 + TUNNEL_NODE, /* Tunnel config node. */
34783 + MPLS_TUNNEL_NODE, /* MPLS Tunnel config node. */
34784 + MPLS_TE_TUNNEL_NODE,
34785 + MPLS_TE_TUNNEL_CONF_NODE,
34786 ZEBRA_NODE, /* zebra connection node. */
34787 TABLE_NODE, /* rtm_table selection node. */
34788 RIP_NODE, /* RIP protocol mode node. */
34789 RIPNG_NODE, /* RIPng protocol mode node. */
34790 + LDP_NODE, /* LDP protocol mode */
34791 + LDP_IF_NODE, /* LDP interface mode */
34792 BGP_NODE, /* BGP protocol mode which includes BGP4+ */
34793 BGP_VPNV4_NODE, /* BGP MPLS-VPN PE exchange. */
34794 BGP_IPV4_NODE, /* BGP IPv4 unicast address family. */
34795 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/lib/if.c quagga-mpls/lib/if.c
34796 --- quagga/lib/if.c 2006-12-12 16:12:06.000000000 -0600
34797 +++ quagga-mpls/lib/if.c 2008-02-19 22:55:33.000000000 -0600
34798 @@ -131,6 +131,7 @@
34799 "name exists already!", ifp->name);
34800 ifp->connected = list_new ();
34801 ifp->connected->del = (void (*) (void *)) connected_free;
34802 + ifp->mpls_labelspace = -1;
34804 if (if_master.if_new_hook)
34805 (*if_master.if_new_hook) (ifp);
34806 @@ -770,6 +771,30 @@
34808 #endif
34810 +struct interface *if_getfirst()
34812 + struct listnode *node = listhead(iflist);
34813 + return listgetdata(node);
34816 +struct interface *if_getnext(struct interface *old)
34818 + struct interface *ifp;
34819 + struct listnode *node;
34820 + int flag = 0;
34822 + for (node = listhead(iflist); node; listnextnode(node)) {
34823 + ifp = listgetdata(node);
34824 + if (flag) {
34825 + return ifp;
34827 + if (ifp->ifindex == old->ifindex) {
34828 + flag = 1;
34831 + return NULL;
34834 #ifndef HAVE_IF_INDEXTONAME
34835 char *
34836 if_indextoname (unsigned int ifindex, char *name)
34837 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/lib/if.h quagga-mpls/lib/if.h
34838 --- quagga/lib/if.h 2007-05-09 15:59:34.000000000 -0500
34839 +++ quagga-mpls/lib/if.h 2008-02-19 22:55:33.000000000 -0600
34840 @@ -133,6 +133,7 @@
34841 #ifdef HAVE_NET_RT_IFLIST
34842 struct if_data stats;
34843 #endif /* HAVE_NET_RT_IFLIST */
34844 + int mpls_labelspace;
34847 /* Connected address structure. */
34848 @@ -291,6 +292,9 @@
34849 extern struct connected *connected_lookup_address (struct interface *,
34850 struct in_addr);
34852 +extern struct interface *if_getfirst();
34853 +extern struct interface *if_getnext(struct interface*);
34855 #ifndef HAVE_IF_NAMETOINDEX
34856 extern unsigned int if_nametoindex (const char *);
34857 #endif
34858 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/lib/log.c quagga-mpls/lib/log.c
34859 --- quagga/lib/log.c 2008-09-04 20:37:36.000000000 -0500
34860 +++ quagga-mpls/lib/log.c 2008-09-07 20:23:32.000000000 -0500
34861 @@ -42,6 +42,8 @@
34862 "ZEBRA",
34863 "RIP",
34864 "BGP",
34865 + "LDP",
34866 + "RSVP",
34867 "OSPF",
34868 "RIPNG",
34869 "OSPF6",
34870 @@ -820,6 +822,9 @@
34871 DESC_ENTRY (ZEBRA_ROUTE_ISIS, "isis", 'I' ),
34872 DESC_ENTRY (ZEBRA_ROUTE_BGP, "bgp", 'B' ),
34873 DESC_ENTRY (ZEBRA_ROUTE_HSLS, "hsls", 'H' ),
34874 + DESC_ENTRY (ZEBRA_ROUTE_LDP, "ldp", 'L' ),
34875 + DESC_ENTRY (ZEBRA_ROUTE_RSVP, "rsvp", 'r' ),
34876 + DESC_ENTRY (ZEBRA_ROUTE_TE, "te", 't' ),
34878 #undef DESC_ENTRY
34880 @@ -847,6 +852,16 @@
34881 DESC_ENTRY (ZEBRA_ROUTER_ID_ADD),
34882 DESC_ENTRY (ZEBRA_ROUTER_ID_DELETE),
34883 DESC_ENTRY (ZEBRA_ROUTER_ID_UPDATE),
34884 + DESC_ENTRY (ZEBRA_MPLS_XC_ADD),
34885 + DESC_ENTRY (ZEBRA_MPLS_XC_DELETE),
34886 + DESC_ENTRY (ZEBRA_MPLS_IN_SEGMENT_ADD),
34887 + DESC_ENTRY (ZEBRA_MPLS_IN_SEGMENT_DELETE),
34888 + DESC_ENTRY (ZEBRA_MPLS_OUT_SEGMENT_ADD),
34889 + DESC_ENTRY (ZEBRA_MPLS_OUT_SEGMENT_DELETE),
34890 + DESC_ENTRY (ZEBRA_MPLS_LABELSPACE_ADD),
34891 + DESC_ENTRY (ZEBRA_MPLS_LABELSPACE_DELETE),
34892 + DESC_ENTRY (ZEBRA_MPLS_FTN_ADD),
34893 + DESC_ENTRY (ZEBRA_MPLS_FTN_DELETE),
34895 #undef DESC_ENTRY
34897 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/lib/log.h quagga-mpls/lib/log.h
34898 --- quagga/lib/log.h 2008-09-04 20:37:36.000000000 -0500
34899 +++ quagga-mpls/lib/log.h 2008-09-07 20:23:54.000000000 -0500
34900 @@ -50,6 +50,8 @@
34901 ZLOG_ZEBRA,
34902 ZLOG_RIP,
34903 ZLOG_BGP,
34904 + ZLOG_LDP,
34905 + ZLOG_RSVP,
34906 ZLOG_OSPF,
34907 ZLOG_RIPNG,
34908 ZLOG_OSPF6,
34909 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/lib/memtypes.c quagga-mpls/lib/memtypes.c
34910 --- quagga/lib/memtypes.c 2007-05-04 15:15:47.000000000 -0500
34911 +++ quagga-mpls/lib/memtypes.c 2008-02-24 00:22:38.000000000 -0600
34912 @@ -83,8 +83,8 @@
34913 { MTYPE_NEXTHOP, "Nexthop" },
34914 { MTYPE_RIB, "RIB" },
34915 { MTYPE_RIB_QUEUE, "RIB process work queue" },
34916 - { MTYPE_STATIC_IPV4, "Static IPv4 route" },
34917 - { MTYPE_STATIC_IPV6, "Static IPv6 route" },
34918 + { MTYPE_STATIC_ROUTE, "Static route" },
34919 + { MTYPE_TE, "Traffic Engineering" },
34920 { -1, NULL },
34923 @@ -242,6 +242,18 @@
34924 { -1, NULL },
34927 +struct memory_list memory_list_ldp[] =
34929 + { MTYPE_LDP, "LDP" },
34930 + { -1, NULL },
34933 +struct memory_list memory_list_rsvp[] =
34935 + { MTYPE_RSVP, "RSVP" },
34936 + { -1, NULL },
34939 struct memory_list memory_list_vtysh[] =
34941 { MTYPE_VTYSH_CONFIG, "Vtysh configuration", },
34942 @@ -258,5 +270,7 @@
34943 { memory_list_ospf6, "OSPF6" },
34944 { memory_list_isis, "ISIS" },
34945 { memory_list_bgp, "BGP" },
34946 + { memory_list_ldp, "LDP" },
34947 + { memory_list_rsvp, "RSVP" },
34948 { NULL, NULL},
34950 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/lib/memtypes.h quagga-mpls/lib/memtypes.h
34951 --- quagga/lib/memtypes.h 2007-05-07 09:25:54.000000000 -0500
34952 +++ quagga-mpls/lib/memtypes.h 2008-02-21 22:43:39.000000000 -0600
34953 @@ -70,8 +70,7 @@
34954 MTYPE_NEXTHOP,
34955 MTYPE_RIB,
34956 MTYPE_RIB_QUEUE,
34957 - MTYPE_STATIC_IPV4,
34958 - MTYPE_STATIC_IPV6,
34959 + MTYPE_STATIC_ROUTE,
34960 MTYPE_BGP,
34961 MTYPE_BGP_PEER,
34962 MTYPE_BGP_PEER_HOST,
34963 @@ -187,6 +186,7 @@
34964 MTYPE_ISIS_ROUTE_INFO,
34965 MTYPE_ISIS_NEXTHOP,
34966 MTYPE_ISIS_NEXTHOP6,
34967 + MTYPE_LDP,
34968 MTYPE_VTYSH_CONFIG,
34969 MTYPE_VTYSH_CONFIG_LINE,
34970 MTYPE_MAX,
34971 @@ -200,6 +200,7 @@
34972 extern struct memory_list memory_list_ospf[];
34973 extern struct memory_list memory_list_ospf6[];
34974 extern struct memory_list memory_list_isis[];
34975 +extern struct memory_list memory_list_ldp[];
34976 extern struct memory_list memory_list_vtysh[];
34978 #endif /* _QUAGGA_MEMTYPES_H */
34979 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/lib/stream.c quagga-mpls/lib/stream.c
34980 --- quagga/lib/stream.c 2008-09-04 20:37:36.000000000 -0500
34981 +++ quagga-mpls/lib/stream.c 2008-09-07 20:23:32.000000000 -0500
34982 @@ -449,6 +449,25 @@
34984 return l;
34987 +/* Get next float from the stream. */
34988 +float
34989 +stream_getf_from (struct stream *s, size_t from)
34991 + u_int32_t l = stream_getl_from (s, from);
34992 + float f;
34993 + ntohf ((float*)&l, &f);
34994 + return f;
34997 +float
34998 +stream_getf (struct stream *s)
35000 + u_int32_t l = stream_getl (s);
35001 + float f;
35002 + ntohf ((float*)&l, &f);
35003 + return f;
35006 /* Copy to source to stream.
35008 @@ -688,6 +707,24 @@
35010 return psize;
35013 +int
35014 +stream_putf (struct stream *s, float f)
35016 + u_int32_t l;
35017 + htonf(&f, (float *)&l);
35018 + stream_putl (s, l);
35019 + return 4;
35022 +int
35023 +stream_putf_at (struct stream *s, size_t putp, float f)
35025 + u_int32_t l;
35026 + htonf(&f, (float *)&l);
35027 + stream_putl_at (s, putp, l);
35028 + return 4;
35031 /* Read size from fd. */
35033 @@ -969,3 +1006,25 @@
35034 stream_fifo_clean (fifo);
35035 XFREE (MTYPE_STREAM_FIFO, fifo);
35038 +void
35039 +htonf (float *src, float *dst)
35041 + u_int32_t lu1, lu2;
35043 + memcpy (&lu1, src, sizeof (u_int32_t));
35044 + lu2 = htonl (lu1);
35045 + memcpy (dst, &lu2, sizeof (u_int32_t));
35046 + return;
35049 +void
35050 +ntohf (float *src, float *dst)
35052 + u_int32_t lu1, lu2;
35054 + memcpy (&lu1, src, sizeof (u_int32_t));
35055 + lu2 = ntohl (lu1);
35056 + memcpy (dst, &lu2, sizeof (u_int32_t));
35057 + return;
35059 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/lib/stream.h quagga-mpls/lib/stream.h
35060 --- quagga/lib/stream.h 2008-09-04 20:37:36.000000000 -0500
35061 +++ quagga-mpls/lib/stream.h 2008-09-07 20:23:32.000000000 -0500
35062 @@ -162,6 +162,8 @@
35063 extern int stream_put_ipv4 (struct stream *, u_int32_t);
35064 extern int stream_put_in_addr (struct stream *, struct in_addr *);
35065 extern int stream_put_prefix (struct stream *, struct prefix *);
35066 +extern int stream_putf (struct stream *, float);
35067 +extern int stream_putf_at (struct stream *, size_t, float);
35069 extern void stream_get (void *, struct stream *, size_t);
35070 extern u_char stream_getc (struct stream *);
35071 @@ -173,6 +175,8 @@
35072 extern uint64_t stream_getq (struct stream *);
35073 extern uint64_t stream_getq_from (struct stream *, size_t);
35074 extern u_int32_t stream_get_ipv4 (struct stream *);
35075 +extern float stream_getf (struct stream *);
35076 +extern float stream_getf_from (struct stream *, size_t);
35078 #undef stream_read
35079 #undef stream_write
35080 @@ -218,4 +222,7 @@
35081 extern void stream_fifo_clean (struct stream_fifo *fifo);
35082 extern void stream_fifo_free (struct stream_fifo *fifo);
35084 +extern void htonf (float *src, float *dst);
35085 +extern void ntohf (float *src, float *dst);
35087 #endif /* _ZEBRA_STREAM_H */
35088 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/lib/table.c quagga-mpls/lib/table.c
35089 --- quagga/lib/table.c 2005-05-03 12:11:25.000000000 -0500
35090 +++ quagga-mpls/lib/table.c 2006-08-09 22:02:40.000000000 -0500
35091 @@ -311,6 +311,37 @@
35092 return NULL;
35095 +struct route_node *
35096 +route_node_lookup2 (struct route_table *table, struct prefix *p)
35098 + struct route_node *rn_in, *rn_tmp;
35100 + if (!(rn_in = route_node_lookup(table,p))) {
35101 +fprintf(stderr,"lookup2 is doing work\n");
35102 + /* walk as far down the tree as we can */
35103 + rn_in = table->top;
35104 + while (rn_in && rn_in->p.prefixlen <= p->prefixlen &&
35105 + prefix_match(&rn_in->p, p)) {
35106 + rn_tmp = rn_in->link[check_bit(&p->u.prefix, rn_in->p.prefixlen)];
35107 + if (!rn_tmp) {
35108 + break;
35110 + rn_in = rn_tmp;
35112 + route_lock_node(rn_in);
35114 + /* rn_in is either the actual node of the furthest node in the tree */
35115 + /* so get the 'next' one with 'info' */
35116 + rn_in = route_next2(rn_in);
35119 + if (rn_in && !rn_in->info) {
35120 + route_unlock_node(rn_in);
35121 + rn_in = NULL;
35123 + return rn_in;
35126 /* Add node to routing table. */
35127 struct route_node *
35128 route_node_get (struct route_table *table, struct prefix *p)
35129 @@ -461,6 +492,22 @@
35130 return NULL;
35133 +struct route_node *
35134 +route_next2 (struct route_node *rn_in)
35136 + struct route_node *rn = rn_in;
35137 + struct route_node *rn2;
35138 + do {
35139 + rn2 = route_next(rn);
35140 + rn = rn2;
35141 + } while(rn && !rn->info);
35143 + if (rn && rn->info) {
35144 + return rn;
35146 + return NULL;
35149 /* Unlock current node and lock next node until limit. */
35150 struct route_node *
35151 route_next_until (struct route_node *node, struct route_node *limit)
35152 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/lib/table.h quagga-mpls/lib/table.h
35153 --- quagga/lib/table.h 2005-05-03 12:11:33.000000000 -0500
35154 +++ quagga-mpls/lib/table.h 2006-08-09 22:02:46.000000000 -0500
35155 @@ -59,12 +59,15 @@
35156 extern void route_node_delete (struct route_node *node);
35157 extern struct route_node *route_top (struct route_table *);
35158 extern struct route_node *route_next (struct route_node *);
35159 +extern struct route_node *route_next2 (struct route_node *);
35160 extern struct route_node *route_next_until (struct route_node *,
35161 struct route_node *);
35162 extern struct route_node *route_node_get (struct route_table *,
35163 struct prefix *);
35164 extern struct route_node *route_node_lookup (struct route_table *,
35165 struct prefix *);
35166 +extern struct route_node *route_node_lookup2 (struct route_table *,
35167 + struct prefix *);
35168 extern struct route_node *route_lock_node (struct route_node *node);
35169 extern struct route_node *route_node_match (struct route_table *,
35170 struct prefix *);
35171 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/lib/thread.c quagga-mpls/lib/thread.c
35172 --- quagga/lib/thread.c 2006-08-27 01:40:36.000000000 -0500
35173 +++ quagga-mpls/lib/thread.c 2006-11-13 20:53:19.000000000 -0600
35174 @@ -416,10 +416,26 @@
35175 sizeof (struct thread_master));
35178 +static int thread_in_list(struct thread_list *list, struct thread *thread)
35180 + struct thread *tt;
35182 + for (tt = list->head; tt; tt = tt->next)
35184 + if (tt == thread)
35186 + return 1;
35189 + return 0;
35192 /* Add a new thread to the list. */
35193 static void
35194 thread_list_add (struct thread_list *list, struct thread *thread)
35196 + assert(!thread_in_list(list,thread));
35198 thread->next = NULL;
35199 thread->prev = list->tail;
35200 if (list->tail)
35201 @@ -436,6 +452,8 @@
35202 struct thread *point,
35203 struct thread *thread)
35205 + assert(!thread_in_list(list,thread));
35207 thread->next = point;
35208 thread->prev = point->prev;
35209 if (point->prev)
35210 @@ -450,6 +468,8 @@
35211 static struct thread *
35212 thread_list_delete (struct thread_list *list, struct thread *thread)
35214 + assert(thread_in_list(list,thread));
35216 if (thread->next)
35217 thread->next->prev = thread->prev;
35218 else
35219 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/lib/vty.c quagga-mpls/lib/vty.c
35220 --- quagga/lib/vty.c 2007-05-09 15:59:34.000000000 -0500
35221 +++ quagga-mpls/lib/vty.c 2008-02-19 22:55:34.000000000 -0600
35222 @@ -690,10 +690,17 @@
35223 /* Nothing to do. */
35224 break;
35225 case CONFIG_NODE:
35226 + case MPLS_LABELSPACE_NODE:
35227 case INTERFACE_NODE:
35228 + case TUNNEL_NODE:
35229 + case MPLS_TUNNEL_NODE:
35230 + case MPLS_TE_TUNNEL_NODE:
35231 + case MPLS_TE_TUNNEL_CONF_NODE:
35232 case ZEBRA_NODE:
35233 case RIP_NODE:
35234 case RIPNG_NODE:
35235 + case LDP_NODE:
35236 + case LDP_IF_NODE:
35237 case BGP_NODE:
35238 case BGP_VPNV4_NODE:
35239 case BGP_IPV4_NODE:
35240 @@ -1097,10 +1104,17 @@
35241 /* Nothing to do. */
35242 break;
35243 case CONFIG_NODE:
35244 + case MPLS_LABELSPACE_NODE:
35245 case INTERFACE_NODE:
35246 + case TUNNEL_NODE:
35247 + case MPLS_TUNNEL_NODE:
35248 + case MPLS_TE_TUNNEL_NODE:
35249 + case MPLS_TE_TUNNEL_CONF_NODE:
35250 case ZEBRA_NODE:
35251 case RIP_NODE:
35252 case RIPNG_NODE:
35253 + case LDP_NODE:
35254 + case LDP_IF_NODE:
35255 case BGP_NODE:
35256 case RMAP_NODE:
35257 case OSPF_NODE:
35258 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/lib/zclient.c quagga-mpls/lib/zclient.c
35259 --- quagga/lib/zclient.c 2007-05-09 15:59:34.000000000 -0500
35260 +++ quagga-mpls/lib/zclient.c 2008-05-11 22:06:38.000000000 -0500
35261 @@ -39,6 +39,11 @@
35262 /* Prototype for event manager. */
35263 static void zclient_event (enum event, struct zclient *);
35265 +#ifdef HAVE_MPLS
35266 +static void mpls_label_stream_write (struct stream *s, struct zmpls_label *label);
35267 +static int mpls_label_stream_read (struct stream *s, struct zmpls_label *label);
35268 +#endif
35270 extern struct thread_master *master;
35272 /* This file local debug flag. */
35273 @@ -399,19 +404,52 @@
35274 * +-+-+-+-+-+-+-+-+
35277 - * A number of IPv4 nexthop(s) or nexthop interface index(es) are then
35278 - * described, as per the Nexthop count. Each nexthop described as:
35279 + * A number of nexthop(s) are then described, as per the Nexthop count.
35280 + * Each nexthop described as:
35282 + * +-+-+-+-+-+-+-+-+
35283 + * | Nexthop Flags | Set to bitwise combination of ZEBRA_NEXTHOP_*
35284 + * +-+-+-+-+-+-+-+-+
35286 + * For each bit in "Nexthop Flags" one of the following is written
35288 + * +-+-+-+-+-+-+-+-+
35289 + * | NEXTHOP_IPV4 |
35290 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35291 + * | IPv4 Nexthop address |
35292 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35294 + * +-+-+-+-+-+-+-+-+
35295 + * | NEXTHOP_IPV6 |
35296 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35297 + * | IPv6 Nexthop address |
35298 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35299 + * ....
35301 * +-+-+-+-+-+-+-+-+
35302 - * | Nexthop Type | Set to one of ZEBRA_NEXTHOP_*
35303 + * |NEXTHOP_IFINDEX|
35304 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35305 - * | IPv4 Nexthop address or Interface Index number |
35306 + * | Interface Index |
35307 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35309 - * Alternatively, if the flags field has ZEBRA_FLAG_BLACKHOLE or
35310 - * ZEBRA_FLAG_REJECT is set then Nexthop count is set to 1, then _no_
35311 - * nexthop information is provided, and the message describes a prefix
35312 - * to blackhole or reject route.
35313 + * +-+-+-+-+-+-+-+-+
35314 + * |NEXTHOP_IFNAME |
35315 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35316 + * | Interface Name |
35317 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35318 + * ....
35320 + * +-+-+-+-+-+-+-+-+
35321 + * | NEXTHOP_DROP |
35322 + * +-+-+-+-+-+-+-+-+
35323 + * | DROP type |
35324 + * +-+-+-+-+-+-+-+-+
35326 + * +-+-+-+-+-+-+-+-+
35327 + * |NEXTHOP_MPLS |
35328 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35329 + * | MPLS value |
35330 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35332 * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
35333 * byte value.
35334 @@ -421,16 +459,106 @@
35336 * XXX: No attention paid to alignment.
35339 +void
35340 +zapi_nexthop_write(struct stream *s, struct zapi_nexthop *nh)
35342 + stream_putc (s, nh->type);
35343 + if (CHECK_FLAG (nh->type, ZEBRA_NEXTHOP_DROP))
35345 + stream_putc (s, ZEBRA_NEXTHOP_DROP);
35346 + stream_putc (s, nh->gw.drop);
35347 + return;
35350 + if (CHECK_FLAG (nh->type, ZEBRA_NEXTHOP_IPV4))
35352 + stream_putc (s, ZEBRA_NEXTHOP_IPV4);
35353 + stream_put_in_addr (s, &nh->gw.ipv4);
35355 +#ifdef HAVE_IPV6
35356 + if (CHECK_FLAG (nh->type, ZEBRA_NEXTHOP_IPV6))
35358 + stream_putc (s, ZEBRA_NEXTHOP_IPV6);
35359 + stream_write (s, (u_char *)&nh->gw.ipv6, 16);
35361 +#endif
35362 + if (CHECK_FLAG (nh->type, ZEBRA_NEXTHOP_IFINDEX))
35364 + stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
35365 + stream_putl (s, nh->intf.index);
35368 + if (CHECK_FLAG (nh->type, ZEBRA_NEXTHOP_IFNAME))
35370 + stream_putc (s, ZEBRA_NEXTHOP_IFNAME);
35371 + stream_put (s, nh->intf.name, INTERFACE_NAMSIZ);
35374 + if (CHECK_FLAG (nh->type, ZEBRA_NEXTHOP_SRC_IPV4))
35376 + stream_putc (s, ZEBRA_NEXTHOP_SRC_IPV4);
35377 + stream_put_in_addr (s, &nh->src.ipv4);
35379 +#ifdef HAVE_IPV6
35380 + if (CHECK_FLAG (nh->type, ZEBRA_NEXTHOP_SRC_IPV6))
35382 + stream_putc (s, ZEBRA_NEXTHOP_SRC_IPV6);
35383 + stream_write (s, (u_char *)&nh->src.ipv6, 16);
35385 +#endif
35387 +#ifdef HAVE_MPLS
35388 + if (CHECK_FLAG (nh->type, ZEBRA_NEXTHOP_MPLS))
35390 + stream_putc (s, ZEBRA_NEXTHOP_MPLS);
35391 + mpls_label_stream_write (s, &nh->mpls);
35393 +#endif
35396 +void
35397 +zapi_nexthop_read(struct stream *s, struct zapi_nexthop *nh)
35399 + char type = stream_getc (s);
35400 + nh->type = type;
35401 + while (type != 0)
35403 + char ntype = stream_getc(s);
35404 + UNSET_FLAG (type, ntype);
35405 + if (CHECK_FLAG (ntype, ZEBRA_NEXTHOP_DROP))
35406 + nh->gw.drop = stream_getc(s);
35407 + else if (CHECK_FLAG (ntype, ZEBRA_NEXTHOP_IPV4))
35408 + nh->gw.ipv4.s_addr = stream_get_ipv4 (s);
35409 +#ifdef HAVE_IPV6
35410 + else if (CHECK_FLAG (ntype, ZEBRA_NEXTHOP_IPV6))
35411 + stream_get (&nh->gw.ipv6, s, 16);
35412 +#endif
35413 + else if (CHECK_FLAG (ntype, ZEBRA_NEXTHOP_IFINDEX))
35414 + nh->intf.index = stream_getl (s);
35415 + else if (CHECK_FLAG (ntype, ZEBRA_NEXTHOP_IFNAME))
35416 + stream_get (nh->intf.name, s, INTERFACE_NAMSIZ);
35417 + else if (CHECK_FLAG (ntype, ZEBRA_NEXTHOP_SRC_IPV4))
35418 + nh->src.ipv4.s_addr = stream_get_ipv4 (s);
35419 +#ifdef HAVE_IPV6
35420 + else if (CHECK_FLAG (ntype, ZEBRA_NEXTHOP_SRC_IPV6))
35421 + stream_get (&nh->src.ipv6, s, 16);
35422 +#endif
35423 +#ifdef HAVE_MPLS
35424 + else if (CHECK_FLAG (ntype, ZEBRA_NEXTHOP_MPLS))
35425 + mpls_label_stream_read(s, &nh->mpls);
35426 +#endif
35431 -zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
35432 +zapi_ipv4_write (u_char cmd, struct stream *s, struct prefix_ipv4 *p,
35433 struct zapi_ipv4 *api)
35435 int i;
35436 int psize;
35437 - struct stream *s;
35439 /* Reset stream. */
35440 - s = zclient->obuf;
35441 stream_reset (s);
35443 zclient_create_header (s, cmd);
35444 @@ -445,31 +573,15 @@
35445 stream_putc (s, p->prefixlen);
35446 stream_write (s, (u_char *) & p->prefix, psize);
35448 - /* Nexthop, ifindex, distance and metric information. */
35449 + /* Nexthop information. */
35450 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
35452 - if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
35454 - stream_putc (s, 1);
35455 - stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
35456 - /* XXX assert(api->nexthop_num == 0); */
35457 - /* XXX assert(api->ifindex_num == 0); */
35459 - else
35460 - stream_putc (s, api->nexthop_num + api->ifindex_num);
35462 + stream_putc (s, api->nexthop_num);
35463 for (i = 0; i < api->nexthop_num; i++)
35465 - stream_putc (s, ZEBRA_NEXTHOP_IPV4);
35466 - stream_put_in_addr (s, api->nexthop[i]);
35468 - for (i = 0; i < api->ifindex_num; i++)
35470 - stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
35471 - stream_putl (s, api->ifindex[i]);
35473 + zapi_nexthop_write(s, &api->nexthop[i]);
35476 + /* distance and metric information. */
35477 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
35478 stream_putc (s, api->distance);
35479 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
35480 @@ -478,20 +590,75 @@
35481 /* Put length at the first point of the stream. */
35482 stream_putw_at (s, 0, stream_get_endp (s));
35484 + return 0;
35487 +int
35488 +zapi_ipv4_read (struct stream *s, zebra_size_t length,
35489 + struct zapi_ipv4 *api, struct prefix_ipv4 *p)
35491 + /* Type, flags, message. */
35492 + api->type = stream_getc (s);
35493 + api->flags = stream_getc (s);
35494 + api->message = stream_getc (s);
35496 + /* IPv4 prefix. */
35497 + memset (p, 0, sizeof (struct prefix_ipv4));
35498 + p->family = AF_INET;
35499 + p->prefixlen = stream_getc (s);
35500 + stream_get (&p->prefix, s, PSIZE (p->prefixlen));
35502 + /* Nexthop, ifindex, distance and metric information. */
35503 + if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
35505 + int count = 0;
35506 + int i = 0;
35508 + count = stream_getc (s);
35509 + while (count > 0)
35511 + zapi_nexthop_read (s, &api->nexthop[i]);
35512 + count--;
35513 + i++;
35516 + api->nexthop_num = i;
35519 + if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
35520 + api->distance = stream_getc (s);
35521 + if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
35522 + api->metric = stream_getl (s);
35524 + return 0;
35527 +int
35528 +zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
35529 + struct zapi_ipv4 *api)
35531 + struct stream *s = zclient->obuf;
35532 + zapi_ipv4_write(cmd, s, p, api);
35533 return zclient_send_message(zclient);
35536 +int
35537 +zapi_ipv4_route_read (struct zclient *zclient, zebra_size_t length,
35538 + struct zapi_ipv4 *api, struct prefix_ipv4 *p)
35540 + struct stream *s = zclient->ibuf;
35541 + return zapi_ipv4_read(s, length, api, p);
35544 #ifdef HAVE_IPV6
35546 -zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
35547 - struct zapi_ipv6 *api)
35548 +zapi_ipv6_write (u_char cmd, struct stream *s, struct prefix_ipv6 *p,
35549 + struct zapi_ipv6 *api)
35551 int i;
35552 int psize;
35553 - struct stream *s;
35555 /* Reset stream. */
35556 - s = zclient->obuf;
35557 stream_reset (s);
35559 zclient_create_header (s, cmd);
35560 @@ -506,23 +673,15 @@
35561 stream_putc (s, p->prefixlen);
35562 stream_write (s, (u_char *)&p->prefix, psize);
35564 - /* Nexthop, ifindex, distance and metric information. */
35565 + /* Nexthop information. */
35566 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
35568 - stream_putc (s, api->nexthop_num + api->ifindex_num);
35570 + stream_putc (s, api->nexthop_num);
35571 for (i = 0; i < api->nexthop_num; i++)
35573 - stream_putc (s, ZEBRA_NEXTHOP_IPV6);
35574 - stream_write (s, (u_char *)api->nexthop[i], 16);
35576 - for (i = 0; i < api->ifindex_num; i++)
35578 - stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
35579 - stream_putl (s, api->ifindex[i]);
35581 + zapi_nexthop_write(s, &api->nexthop[i]);
35584 + /* distance and metric information. */
35585 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
35586 stream_putc (s, api->distance);
35587 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
35588 @@ -531,8 +690,65 @@
35589 /* Put length at the first point of the stream. */
35590 stream_putw_at (s, 0, stream_get_endp (s));
35592 + return 0;
35595 +int
35596 +zapi_ipv6_read (struct stream *s, zebra_size_t length,
35597 + struct zapi_ipv6 *api, struct prefix_ipv6 *p)
35599 + /* Type, flags, message. */
35600 + api->type = stream_getc (s);
35601 + api->flags = stream_getc (s);
35602 + api->message = stream_getc (s);
35604 + /* IPv4 prefix. */
35605 + memset (p, 0, sizeof (struct prefix_ipv6));
35606 + p->family = AF_INET6;
35607 + p->prefixlen = stream_getc (s);
35608 + stream_get (&p->prefix, s, PSIZE (p->prefixlen));
35610 + /* Nexthop, ifindex, distance and metric information. */
35611 + if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
35613 + int count = 0;
35614 + int i = 0;
35616 + count = stream_getc (s);
35617 + while (count > 0)
35619 + zapi_nexthop_read (s, &api->nexthop[i]);
35620 + count--;
35621 + i++;
35624 + api->nexthop_num = i;
35627 + if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
35628 + api->distance = stream_getc (s);
35629 + if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
35630 + api->metric = stream_getl (s);
35632 + return 0;
35635 +int
35636 +zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
35637 + struct zapi_ipv6 *api)
35639 + struct stream *s = zclient->obuf;
35640 + zapi_ipv6_write(cmd, s, p, api);
35641 return zclient_send_message(zclient);
35644 +int
35645 +zapi_ipv6_route_read (struct zclient *zclient, zebra_size_t length,
35646 + struct zapi_ipv6 *api, struct prefix_ipv6 *p)
35648 + struct stream *s = zclient->ibuf;
35649 + return zapi_ipv6_read (s, length, api, p);
35651 #endif /* HAVE_IPV6 */
35654 @@ -541,6 +757,545 @@
35655 * then set/unset redist[type] in the client handle (a struct zserv) for the
35656 * sending client
35659 +#ifdef HAVE_MPLS
35661 +static void
35662 +mpls_label_stream_write (struct stream *s, struct zmpls_label *label)
35664 + /* Put label type. */
35665 + stream_putc (s, label->type);
35667 + /* put the label value */
35668 + switch (label->type)
35670 + case ZEBRA_MPLS_LABEL_GEN:
35671 + stream_putl (s, label->u.gen);
35672 + break;
35673 + case ZEBRA_MPLS_LABEL_ATM:
35674 + stream_putw (s, label->u.atm.vci);
35675 + stream_putw (s, label->u.atm.vpi);
35676 + break;
35677 + case ZEBRA_MPLS_LABEL_FR:
35678 + stream_putl (s, label->u.fr);
35679 + break;
35680 + default:
35681 + assert(0);
35685 +int
35686 +mpls_label_stream_read (struct stream *s, struct zmpls_label *label)
35688 + /* get the label type */
35689 + label->type = stream_getc (s);
35691 + /* get the label value */
35692 + switch (label->type)
35694 + case ZEBRA_MPLS_LABEL_GEN:
35695 + label->u.gen = stream_getl (s);
35696 + break;
35697 + case ZEBRA_MPLS_LABEL_ATM:
35698 + label->u.atm.vci = stream_getw (s);
35699 + label->u.atm.vpi = stream_getw (s);
35700 + break;
35701 + case ZEBRA_MPLS_LABEL_FR:
35702 + label->u.fr = stream_getl (s);
35703 + break;
35704 + default:
35705 + assert(0);
35707 + return 0;
35710 +static void
35711 +mpls_fec_stream_write (struct stream *s, struct zmpls_fec *fec)
35713 + int psize;
35715 + /* Put FEC type. */
35716 + stream_putc (s, fec->type);
35717 + stream_putc (s, fec->owner);
35719 + /* put the label value */
35720 + switch (fec->type)
35722 + case ZEBRA_MPLS_FEC_IPV4:
35723 + case ZEBRA_MPLS_FEC_IPV6:
35724 + /* Put prefix information. */
35725 + psize = PSIZE (fec->u.p.prefixlen);
35726 + stream_putc (s, fec->u.p.prefixlen);
35727 + stream_write (s, (u_char *)&fec->u.p.u.prefix, psize);
35728 + break;
35729 + case ZEBRA_MPLS_FEC_L2:
35730 + stream_put (s, fec->u.l2_ifname, INTERFACE_NAMSIZ);
35731 + break;
35732 + default:
35733 + assert(0);
35737 +static int
35738 +mpls_fec_stream_read (struct stream *s, struct zmpls_fec *fec)
35740 + /* get the fec type */
35741 + fec->type = stream_getc (s);
35742 + fec->owner = stream_getc (s);
35744 + /* get the fec value */
35745 + switch (fec->type)
35747 + case ZEBRA_MPLS_FEC_IPV4:
35748 + case ZEBRA_MPLS_FEC_IPV6:
35749 + memset (&fec->u.p, 0, sizeof (struct prefix));
35751 + if (fec->type == ZEBRA_MPLS_FEC_IPV4)
35752 + fec->u.p.family = AF_INET;
35753 + else
35754 + fec->u.p.family = AF_INET6;
35756 + fec->u.p.prefixlen = stream_getc (s);
35757 + stream_get (&fec->u.p.u.prefix, s, PSIZE (fec->u.p.prefixlen));
35758 + break;
35759 + case ZEBRA_MPLS_FEC_L2:
35760 + stream_get (fec->u.l2_ifname, s, INTERFACE_NAMSIZ);
35761 + break;
35762 + default:
35763 + assert(0);
35766 + return 0;
35769 +void
35770 +mpls_ftn_stream_write (struct stream *s, struct zapi_mpls_ftn *api)
35772 + stream_putc (s, api->owner);
35774 + /* the FEC we're binding to */
35775 + mpls_fec_stream_write (s, &api->fec);
35777 + /* out-segment index */
35778 + stream_putl (s, api->out_index);
35781 +int
35782 +mpls_ftn_stream_read (struct stream *s, struct zapi_mpls_ftn *api)
35784 + api->owner = stream_getc (s);
35786 + mpls_fec_stream_read (s, &api->fec);
35788 + api->out_index = stream_getl (s);
35789 + return 0;
35792 +void
35793 +mpls_xc_stream_write (struct stream *s, struct zapi_mpls_xc *api)
35795 + stream_putc (s, api->owner);
35797 + stream_putc (s, api->in_labelspace);
35798 + mpls_label_stream_write (s, &api->in_label);
35800 + stream_putl (s, api->out_index);
35803 +int
35804 +mpls_xc_stream_read (struct stream *s, struct zapi_mpls_xc *api)
35806 + api->owner = stream_getc (s);
35807 + api->in_labelspace = stream_getc (s);
35808 + mpls_label_stream_read (s, &api->in_label);
35810 + api->out_index = stream_getl (s);
35811 + return 0;
35814 +void
35815 +mpls_in_segment_stream_write (struct stream *s,
35816 + struct zapi_mpls_in_segment *api)
35818 + stream_putc (s, api->owner);
35819 + stream_putc (s, api->labelspace);
35820 + stream_putw (s, api->protocol);
35821 + stream_putc (s, api->pop);
35823 + mpls_label_stream_write (s, &api->label);
35826 +int
35827 +mpls_in_segment_stream_read (struct stream *s,
35828 + struct zapi_mpls_in_segment *api)
35830 + api->owner = stream_getc (s);
35831 + api->labelspace = stream_getc (s);
35832 + api->protocol = stream_getw (s);
35833 + api->pop = stream_getc (s);
35835 + mpls_label_stream_read (s, &api->label);
35836 + return 0;
35839 +void
35840 +mpls_out_segment_stream_write (struct stream *s,
35841 + struct zapi_mpls_out_segment *api)
35843 + stream_putc (s, api->owner);
35844 + zapi_nexthop_write(s, &api->nh);
35845 + stream_putl (s, api->index);
35846 + stream_putl (s, api->req);
35849 +int
35850 +mpls_out_segment_stream_read (struct stream *s,
35851 + struct zapi_mpls_out_segment *api)
35853 + api->owner = stream_getc (s);
35854 + zapi_nexthop_read(s, &api->nh);
35855 + api->index = stream_getl (s);
35856 + api->req = stream_getl (s);
35857 + return 0;
35860 +void
35861 +mpls_labelspace_stream_write (struct stream *s,
35862 + struct zapi_mpls_labelspace *api)
35864 + stream_putc (s, api->owner);
35865 + stream_putc (s, api->labelspace);
35866 + stream_put (s, api->ifname, INTERFACE_NAMSIZ);
35869 +int
35870 +mpls_labelspace_stream_read (struct stream *s,
35871 + struct zapi_mpls_labelspace *api)
35873 + api->owner = stream_getc (s);
35874 + api->labelspace = stream_getc (s);
35875 + stream_get (api->ifname, s, INTERFACE_NAMSIZ);
35877 + return 0;
35880 +static int
35881 +zapi_mpls_xc (struct zclient *zclient, struct zapi_mpls_xc *api, u_char cmd)
35883 + struct stream *s;
35885 + /* Reset stream. */
35886 + s = zclient->obuf;
35887 + stream_reset (s);
35889 + zclient_create_header (s, cmd);
35891 + mpls_xc_stream_write(s, api);
35893 + /* Put length at the first point of the stream. */
35894 + stream_putw_at (s, 0, stream_get_endp (s));
35896 + return zclient_send_message(zclient);
35899 +int
35900 +zapi_mpls_xc_add (struct zclient *zclient, struct zapi_mpls_xc *api)
35902 + return zapi_mpls_xc (zclient, api, ZEBRA_MPLS_XC_ADD);
35905 +int
35906 +zapi_mpls_xc_delete (struct zclient *zclient, struct zapi_mpls_xc *api)
35908 + return zapi_mpls_xc (zclient, api, ZEBRA_MPLS_XC_DELETE);
35911 +static int
35912 +zapi_mpls_in_segment (struct zclient *zclient,
35913 + struct zapi_mpls_in_segment *api, u_char cmd)
35915 + struct stream *s;
35917 + /* Reset stream. */
35918 + s = zclient->obuf;
35919 + stream_reset (s);
35921 + zclient_create_header (s, cmd);
35923 + mpls_in_segment_stream_write(s, api);
35925 + /* Put length at the first point of the stream. */
35926 + stream_putw_at (s, 0, stream_get_endp (s));
35928 + return zclient_send_message(zclient);
35931 +int
35932 +zapi_mpls_in_segment_add (struct zclient *zclient,
35933 + struct zapi_mpls_in_segment *api)
35935 + return zapi_mpls_in_segment (zclient, api, ZEBRA_MPLS_IN_SEGMENT_ADD);
35938 +int
35939 +zapi_mpls_in_segment_delete (struct zclient *zclient,
35940 + struct zapi_mpls_in_segment *api)
35942 + return zapi_mpls_in_segment (zclient, api, ZEBRA_MPLS_IN_SEGMENT_DELETE);
35945 +static int
35946 +zapi_mpls_out_segment (struct zclient *zclient,
35947 + struct zapi_mpls_out_segment *api, u_char cmd)
35949 + struct stream *s;
35951 + /* Reset stream. */
35952 + s = zclient->obuf;
35953 + stream_reset (s);
35955 + zclient_create_header (s, cmd);
35957 + mpls_out_segment_stream_write(s, api);
35959 + /* Put length at the first point of the stream. */
35960 + stream_putw_at (s, 0, stream_get_endp (s));
35962 + return zclient_send_message(zclient);
35965 +int
35966 +zapi_mpls_out_segment_add (struct zclient *zclient,
35967 + struct zapi_mpls_out_segment *api)
35969 + return zapi_mpls_out_segment (zclient, api, ZEBRA_MPLS_OUT_SEGMENT_ADD);
35972 +int
35973 +zapi_mpls_out_segment_delete (struct zclient *zclient,
35974 + struct zapi_mpls_out_segment *api)
35976 + return zapi_mpls_out_segment (zclient, api, ZEBRA_MPLS_OUT_SEGMENT_DELETE);
35979 +static int
35980 +zapi_mpls_labelspace (struct zclient *zclient,
35981 + struct zapi_mpls_labelspace *api, u_char cmd)
35983 + struct stream *s;
35985 + /* Reset stream. */
35986 + s = zclient->obuf;
35987 + stream_reset (s);
35989 + zclient_create_header (s, cmd);
35991 + mpls_labelspace_stream_write(s, api);
35993 + /* Put length at the first point of the stream. */
35994 + stream_putw_at (s, 0, stream_get_endp (s));
35996 + return zclient_send_message(zclient);
35999 +int
36000 +zapi_mpls_labelspace_add (struct zclient *zclient,
36001 + struct zapi_mpls_labelspace *api)
36003 + return zapi_mpls_labelspace (zclient, api, ZEBRA_MPLS_LABELSPACE_ADD);
36006 +int
36007 +zapi_mpls_labelspace_delete (struct zclient *zclient,
36008 + struct zapi_mpls_labelspace *api)
36010 + return zapi_mpls_labelspace (zclient, api, ZEBRA_MPLS_LABELSPACE_DELETE);
36013 +static int
36014 +zapi_mpls_ftn (struct zclient *zclient, struct zapi_mpls_ftn *api, u_char cmd)
36016 + struct stream *s;
36018 + /* Reset stream. */
36019 + s = zclient->obuf;
36020 + stream_reset (s);
36022 + zclient_create_header (s, cmd);
36024 + mpls_ftn_stream_write(s, api);
36026 + /* Put length at the first point of the stream. */
36027 + stream_putw_at (s, 0, stream_get_endp (s));
36029 + return zclient_send_message(zclient);
36032 +int
36033 +zapi_mpls_ftn_add (struct zclient *zclient, struct zapi_mpls_ftn *api)
36035 + return zapi_mpls_ftn (zclient, api, ZEBRA_MPLS_FTN_ADD);
36038 +int
36039 +zapi_mpls_ftn_delete (struct zclient *zclient, struct zapi_mpls_ftn *api)
36041 + return zapi_mpls_ftn (zclient, api, ZEBRA_MPLS_FTN_DELETE);
36044 +int
36045 +mpls_label_match (struct zmpls_label *a, struct zmpls_label *b)
36047 + if (a->type != b->type)
36048 + return 0;
36050 + switch (a->type)
36052 + case ZEBRA_MPLS_LABEL_GEN:
36053 + if (a->u.gen != b->u.gen)
36054 + return 0;
36055 + break;
36056 + case ZEBRA_MPLS_LABEL_ATM:
36057 + if (a->u.atm.vci != b->u.atm.vci &&
36058 + a->u.atm.vpi != b->u.atm.vpi)
36059 + return 0;
36060 + break;
36061 + case ZEBRA_MPLS_LABEL_FR:
36062 + if (a->u.fr != b->u.fr)
36063 + return 0;
36064 + break;
36065 + default:
36066 + assert(0);
36068 + return 1;
36071 +int
36072 +mpls_fec_match(struct zmpls_fec *a, struct zmpls_fec *b)
36074 + if (a->type != b->type)
36075 + return 0;
36077 + switch (a->type)
36079 + case ZEBRA_MPLS_FEC_IPV4:
36080 + case ZEBRA_MPLS_FEC_IPV6:
36081 + if (!prefix_same(&a->u.p, &b->u.p))
36083 + return 0;
36085 + break;
36086 + case ZEBRA_MPLS_FEC_L2:
36087 + if (strncmp(a->u.l2_ifname, b->u.l2_ifname, INTERFACE_NAMSIZ))
36089 + return 0;
36091 + break;
36092 + default:
36093 + assert(0);
36095 + return 1;
36098 +#endif
36100 + * NOTE when doing nexthop comparison, some IPv4 nexthop have ifindex
36101 + * and some do not. We only need to check the ifindex if this is not a
36102 + * IPv4 nexthop or if the both have ifindices
36103 + */
36105 +int
36106 +zapi_nexthop_match(struct zapi_nexthop *a, struct zapi_nexthop *b, int mask)
36108 + int either = (a->type | b->type) & mask;
36109 + int both = (a->type & b->type) & mask;
36110 + int try = 0;
36111 + int match = 0;
36112 + int v4_gate_match = 0;
36114 + try++;
36115 + if (a->advmss == b->advmss)
36116 + match++;
36118 + if (CHECK_FLAG (either, ZEBRA_NEXTHOP_DROP))
36120 + try++;
36121 + if (CHECK_FLAG (both, ZEBRA_NEXTHOP_DROP) &&
36122 + a->gw.drop == b->gw.drop)
36123 + match++;
36125 + else if (CHECK_FLAG (either, ZEBRA_NEXTHOP_IPV4))
36127 + try++;
36128 + if (CHECK_FLAG (both, ZEBRA_NEXTHOP_IPV4) &&
36129 + IPV4_ADDR_SAME (&a->gw.ipv4, &b->gw.ipv4))
36131 + match++;
36132 + v4_gate_match = 1;
36135 +#ifdef HAVE_IPV6
36136 + else if (CHECK_FLAG (either, ZEBRA_NEXTHOP_IPV6))
36138 + try++;
36139 + if (CHECK_FLAG (both, ZEBRA_NEXTHOP_IPV6) &&
36140 + IPV6_ADDR_SAME (&a->gw.ipv6, &b->gw.ipv6))
36141 + match++;
36143 +#endif
36145 + if (CHECK_FLAG(either, ZEBRA_NEXTHOP_SRC_IPV4))
36147 + try++;
36148 + if (CHECK_FLAG(both, ZEBRA_NEXTHOP_SRC_IPV4) &&
36149 + IPV4_ADDR_SAME (&a->src.ipv4, &b->src.ipv4))
36150 + match++;
36152 +#ifdef HAVE_IPV6
36153 + else if (CHECK_FLAG(either, ZEBRA_NEXTHOP_SRC_IPV6))
36155 + try++;
36156 + if (CHECK_FLAG(both, ZEBRA_NEXTHOP_SRC_IPV6) &&
36157 + IPV6_ADDR_SAME (&a->src.ipv6, &b->src.ipv6))
36158 + match++;
36160 +#endif
36162 + if (CHECK_FLAG (either, ZEBRA_NEXTHOP_IFNAME))
36164 + try++;
36165 + if (CHECK_FLAG (both, ZEBRA_NEXTHOP_IFNAME) &&
36166 + strcmp (&a->intf.name, &b->intf.name) == 0)
36167 + match++;
36169 + else if (CHECK_FLAG (either, ZEBRA_NEXTHOP_IFINDEX))
36171 + if (!v4_gate_match)
36173 + try++;
36174 + if (CHECK_FLAG (both, ZEBRA_NEXTHOP_IFINDEX) &&
36175 + (a->intf.index == b->intf.index))
36176 + match++;
36178 + else if (CHECK_FLAG (both, ZEBRA_NEXTHOP_IFINDEX))
36180 + try++;
36181 + if (a->intf.index == b->intf.index)
36182 + match++;
36185 +#ifdef HAVE_MPLS
36186 + if (CHECK_FLAG (either, ZEBRA_NEXTHOP_MPLS))
36188 + try++;
36189 + if (CHECK_FLAG (both, ZEBRA_NEXTHOP_MPLS) &&
36190 + mpls_label_match(&a->mpls, &b->mpls))
36191 + match++;
36193 +#endif
36194 + return (try && try == match) ? 1 : 0;
36198 zebra_redistribute_send (int command, struct zclient *zclient, int type)
36200 @@ -937,6 +1692,46 @@
36201 if (zclient->ipv6_route_delete)
36202 ret = (*zclient->ipv6_route_delete) (command, zclient, length);
36203 break;
36204 + case ZEBRA_MPLS_XC_ADD:
36205 + if (zclient->mpls_xc_add)
36206 + ret = (*zclient->mpls_xc_add) (command, zclient, length);
36207 + break;
36208 + case ZEBRA_MPLS_XC_DELETE:
36209 + if (zclient->mpls_xc_delete)
36210 + ret = (*zclient->mpls_xc_delete) (command, zclient, length);
36211 + break;
36212 + case ZEBRA_MPLS_IN_SEGMENT_ADD:
36213 + if (zclient->mpls_in_segment_add)
36214 + ret = (*zclient->mpls_in_segment_add) (command, zclient, length);
36215 + break;
36216 + case ZEBRA_MPLS_IN_SEGMENT_DELETE:
36217 + if (zclient->mpls_in_segment_delete)
36218 + ret = (*zclient->mpls_in_segment_delete) (command, zclient, length);
36219 + break;
36220 + case ZEBRA_MPLS_OUT_SEGMENT_ADD:
36221 + if (zclient->mpls_out_segment_add)
36222 + ret = (*zclient->mpls_out_segment_add) (command, zclient, length);
36223 + break;
36224 + case ZEBRA_MPLS_OUT_SEGMENT_DELETE:
36225 + if (zclient->mpls_out_segment_delete)
36226 + ret = (*zclient->mpls_out_segment_delete) (command, zclient, length);
36227 + break;
36228 + case ZEBRA_MPLS_LABELSPACE_ADD:
36229 + if (zclient->mpls_labelspace_add)
36230 + ret = (*zclient->mpls_labelspace_add) (command, zclient, length);
36231 + break;
36232 + case ZEBRA_MPLS_LABELSPACE_DELETE:
36233 + if (zclient->mpls_labelspace_delete)
36234 + ret = (*zclient->mpls_labelspace_delete) (command, zclient, length);
36235 + break;
36236 + case ZEBRA_MPLS_FTN_ADD:
36237 + if (zclient->mpls_ftn_add)
36238 + ret = (*zclient->mpls_ftn_add) (command, zclient, length);
36239 + break;
36240 + case ZEBRA_MPLS_FTN_DELETE:
36241 + if (zclient->mpls_ftn_delete)
36242 + ret = (*zclient->mpls_ftn_delete) (command, zclient, length);
36243 + break;
36244 default:
36245 break;
36247 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/lib/zclient.h quagga-mpls/lib/zclient.h
36248 --- quagga/lib/zclient.h 2006-01-31 14:55:54.000000000 -0600
36249 +++ quagga-mpls/lib/zclient.h 2008-02-22 01:45:25.000000000 -0600
36250 @@ -24,6 +24,7 @@
36252 /* For struct interface and struct connected. */
36253 #include "if.h"
36254 +#include "prefix.h"
36256 /* For input/output buffer to zebra. */
36257 #define ZEBRA_MAX_PACKET_SIZ 4096
36258 @@ -31,6 +32,9 @@
36259 /* Zebra header size. */
36260 #define ZEBRA_HEADER_SIZE 6
36262 +/* Zebra maximum number of nexthops per API struct */
36263 +#define ZEBRA_MAX_NEXTHOP 8
36265 /* Structure for the zebra client. */
36266 struct zclient
36268 @@ -67,6 +71,9 @@
36269 /* Redistribute defauilt. */
36270 u_char default_information;
36272 + /* Router-id information. */
36273 + u_char ridinfo;
36275 /* Pointer to the callback functions. */
36276 int (*router_id_update) (int, struct zclient *, uint16_t);
36277 int (*interface_add) (int, struct zclient *, uint16_t);
36278 @@ -79,6 +86,16 @@
36279 int (*ipv4_route_delete) (int, struct zclient *, uint16_t);
36280 int (*ipv6_route_add) (int, struct zclient *, uint16_t);
36281 int (*ipv6_route_delete) (int, struct zclient *, uint16_t);
36282 + int (*mpls_xc_add) (int, struct zclient *, uint16_t);
36283 + int (*mpls_xc_delete) (int, struct zclient *, uint16_t);
36284 + int (*mpls_in_segment_add) (int, struct zclient *, uint16_t);
36285 + int (*mpls_in_segment_delete) (int, struct zclient *, uint16_t);
36286 + int (*mpls_out_segment_add) (int, struct zclient *, uint16_t);
36287 + int (*mpls_out_segment_delete) (int, struct zclient *, uint16_t);
36288 + int (*mpls_labelspace_add) (int, struct zclient *, uint16_t);
36289 + int (*mpls_labelspace_delete) (int, struct zclient *, uint16_t);
36290 + int (*mpls_ftn_add) (int, struct zclient *, uint16_t);
36291 + int (*mpls_ftn_delete) (int, struct zclient *, uint16_t);
36294 /* Zebra API message flag. */
36295 @@ -95,10 +112,58 @@
36296 * always set to 255 in new zserv.
36298 uint8_t version;
36299 -#define ZSERV_VERSION 1
36300 +#define ZSERV_VERSION 2
36301 uint16_t command;
36304 +#ifdef HAVE_MPLS
36306 +#define ZEBRA_MPLS_LABEL_GEN 1
36307 +#define ZEBRA_MPLS_LABEL_ATM 2
36308 +#define ZEBRA_MPLS_LABEL_FR 3
36310 +struct zmpls_label
36312 + u_char type;
36313 + union {
36314 + u_int32_t gen;
36315 + u_int32_t fr;
36316 + struct {
36317 + u_int16_t vpi;
36318 + u_int16_t vci;
36319 + } atm;
36320 + } u;
36322 +#endif
36324 +struct zapi_nexthop {
36325 + u_char type;
36326 + union
36328 + char name[INTERFACE_NAMSIZ + 1];
36329 + unsigned int index;
36330 + } intf;
36331 + union
36333 + struct in_addr ipv4;
36334 +#ifdef HAVE_IPV6
36335 + struct in6_addr ipv6;
36336 +#endif
36337 + u_char drop;
36338 + } gw;
36339 + union
36341 + struct in_addr ipv4;
36342 + struct in6_addr ipv6;
36343 + } src;
36345 + /* Advertised MSS */
36346 + int advmss;
36347 +#ifdef HAVE_MPLS
36348 + struct zmpls_label mpls;
36349 +#endif
36352 /* Zebra IPv4 route message API. */
36353 struct zapi_ipv4
36355 @@ -109,10 +174,7 @@
36356 u_char message;
36358 u_char nexthop_num;
36359 - struct in_addr **nexthop;
36361 - u_char ifindex_num;
36362 - unsigned int *ifindex;
36363 + struct zapi_nexthop nexthop[8];
36365 u_char distance;
36367 @@ -153,8 +215,19 @@
36368 extern struct connected *zebra_interface_address_read (int, struct stream *);
36369 extern void zebra_interface_if_set_value (struct stream *, struct interface *);
36370 extern void zebra_router_id_update_read (struct stream *s, struct prefix *rid);
36372 +extern void zapi_nexthop_write(struct stream *s, struct zapi_nexthop *nh);
36373 +extern void zapi_nexthop_read(struct stream *s, struct zapi_nexthop *nh);
36375 +extern int zapi_ipv4_write (u_char cmd, struct stream *s, struct prefix_ipv4 *p,
36376 + struct zapi_ipv4 *api);
36377 +extern int zapi_ipv4_read (struct stream *, zebra_size_t, struct zapi_ipv4 *,
36378 + struct prefix_ipv4 *);
36380 extern int zapi_ipv4_route (u_char, struct zclient *, struct prefix_ipv4 *,
36381 struct zapi_ipv4 *);
36382 +extern int zapi_ipv4_route_read (struct zclient *, zebra_size_t, struct zapi_ipv4 *,
36383 + struct prefix_ipv4 *);
36385 #ifdef HAVE_IPV6
36386 /* IPv6 prefix add and delete function prototype. */
36387 @@ -168,18 +241,162 @@
36388 u_char message;
36390 u_char nexthop_num;
36391 - struct in6_addr **nexthop;
36393 - u_char ifindex_num;
36394 - unsigned int *ifindex;
36395 + struct zapi_nexthop nexthop[8];
36397 u_char distance;
36399 u_int32_t metric;
36402 +extern int zapi_ipv6_write (u_char cmd, struct stream *s, struct prefix_ipv6 *p,
36403 + struct zapi_ipv6 *api);
36404 +extern int zapi_ipv6_read (struct stream *, zebra_size_t, struct zapi_ipv6 *,
36405 + struct prefix_ipv6 *);
36407 extern int zapi_ipv6_route (u_char cmd, struct zclient *zclient,
36408 - struct prefix_ipv6 *p, struct zapi_ipv6 *api);
36409 + struct prefix_ipv6 *p, struct zapi_ipv6 *api);
36410 +extern int zapi_ipv6_route_read (struct zclient *, zebra_size_t, struct zapi_ipv6 *,
36411 + struct prefix_ipv6 *);
36412 #endif /* HAVE_IPV6 */
36414 +#ifdef HAVE_MPLS
36416 +#define ZEBRA_MPLS_FEC_IPV4 1
36417 +#define ZEBRA_MPLS_FEC_IPV6 2
36418 +#define ZEBRA_MPLS_FEC_L2 3
36420 +struct zmpls_fec
36422 + u_char type;
36423 + char owner;
36424 + union {
36425 + struct prefix p;
36426 + char l2_ifname[INTERFACE_NAMSIZ + 1];
36427 + } u;
36430 +/* structures used by clients */
36432 +struct zapi_mpls_xc
36434 + u_int index;
36435 + u_char owner;
36436 + u_char in_labelspace;
36437 + struct zmpls_label in_label;
36438 + u_int out_index;
36441 +struct zapi_mpls_in_segment
36443 + u_char owner;
36444 + u_char labelspace;
36445 + u_short protocol;
36446 + u_char pop;
36447 + struct zmpls_label label;
36450 +struct zapi_mpls_out_segment
36452 + u_char owner;
36453 + /* label is embeded in zapi_nexthop */
36454 + struct zapi_nexthop nh;
36455 + u_int index;
36456 + int req;
36459 +struct zapi_mpls_labelspace
36461 + u_char owner;
36462 + char labelspace;
36463 + char ifname[INTERFACE_NAMSIZ + 1];
36466 +struct zapi_mpls_ftn
36468 + u_char owner;
36469 + struct zmpls_fec fec;
36470 + u_int out_index;
36473 +int
36474 +mpls_label_match (struct zmpls_label *a, struct zmpls_label *b);
36476 +int
36477 +mpls_fec_match (struct zmpls_fec *a, struct zmpls_fec *b);
36479 +int
36480 +zapi_nexthop_match(struct zapi_nexthop *a, struct zapi_nexthop *b, int mask);
36482 +void
36483 +mpls_xc_stream_write (struct stream *s, struct zapi_mpls_xc *api);
36485 +int
36486 +mpls_xc_stream_read (struct stream *s, struct zapi_mpls_xc *api);
36488 +void
36489 +mpls_in_segment_stream_write (struct stream *s,
36490 + struct zapi_mpls_in_segment *api);
36491 +int
36492 +mpls_in_segment_stream_read (struct stream *s,
36493 + struct zapi_mpls_in_segment *api);
36495 +void
36496 +mpls_out_segment_stream_write (struct stream *s,
36497 + struct zapi_mpls_out_segment *api);
36498 +int
36499 +mpls_out_segment_stream_read (struct stream *s,
36500 + struct zapi_mpls_out_segment *api);
36502 +void
36503 +mpls_labelspace_stream_write (struct stream *s,
36504 + struct zapi_mpls_labelspace *api);
36505 +int
36506 +mpls_labelspace_stream_read (struct stream *s,
36507 + struct zapi_mpls_labelspace *api);
36509 +void
36510 +mpls_ftn_stream_write (struct stream *s,
36511 + struct zapi_mpls_ftn *api);
36512 +int
36513 +mpls_ftn_stream_read (struct stream *s,
36514 + struct zapi_mpls_ftn *api);
36516 +int
36517 +zapi_mpls_xc_add (struct zclient *zclient, struct zapi_mpls_xc *api);
36519 +int
36520 +zapi_mpls_xc_delete (struct zclient *zclient, struct zapi_mpls_xc *api);
36522 +int
36523 +zapi_mpls_in_segment_add (struct zclient *zclient,
36524 + struct zapi_mpls_in_segment *api);
36526 +int
36527 +zapi_mpls_in_segment_delete (struct zclient *zclient,
36528 + struct zapi_mpls_in_segment *api);
36530 +int
36531 +zapi_mpls_out_segment_add (struct zclient *zclient,
36532 + struct zapi_mpls_out_segment *api);
36534 +int
36535 +zapi_mpls_out_segment_delete (struct zclient *zclient,
36536 + struct zapi_mpls_out_segment *api);
36538 +int
36539 +zapi_mpls_labelspace_add (struct zclient *zclient,
36540 + struct zapi_mpls_labelspace *api);
36542 +int
36543 +zapi_mpls_labelspace_delete (struct zclient *zclient,
36544 + struct zapi_mpls_labelspace *api);
36546 +int
36547 +zapi_mpls_ftn_add (struct zclient *zclient, struct zapi_mpls_ftn *api);
36549 +int
36550 +zapi_mpls_ftn_delete (struct zclient *zclient,
36551 + struct zapi_mpls_ftn *api);
36553 +#endif /* HAVE_MPLS */
36554 #endif /* _ZEBRA_ZCLIENT_H */
36555 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/lib/zebra.h quagga-mpls/lib/zebra.h
36556 --- quagga/lib/zebra.h 2008-09-04 20:37:36.000000000 -0500
36557 +++ quagga-mpls/lib/zebra.h 2008-09-07 20:25:24.000000000 -0500
36558 @@ -159,11 +159,16 @@
36559 #include <net/route.h>
36560 #endif /* HAVE_NET_ROUTE_H */
36562 +#undef __STRICT_ANSI__
36564 #ifdef HAVE_NETLINK
36565 #include <linux/netlink.h>
36566 #include <linux/rtnetlink.h>
36567 #include <linux/filter.h>
36568 #include <stddef.h>
36569 +#if defined(HAVE_MPLS) && defined(LINUX_MPLS)
36570 +#include <linux/genetlink.h>
36571 +#endif
36572 #else
36573 #define RT_TABLE_MAIN 0
36574 #endif /* HAVE_NETLINK */
36575 @@ -413,7 +418,17 @@
36576 #define ZEBRA_ROUTER_ID_ADD 20
36577 #define ZEBRA_ROUTER_ID_DELETE 21
36578 #define ZEBRA_ROUTER_ID_UPDATE 22
36579 -#define ZEBRA_MESSAGE_MAX 23
36580 +#define ZEBRA_MPLS_XC_ADD 23
36581 +#define ZEBRA_MPLS_XC_DELETE 24
36582 +#define ZEBRA_MPLS_IN_SEGMENT_ADD 25
36583 +#define ZEBRA_MPLS_IN_SEGMENT_DELETE 26
36584 +#define ZEBRA_MPLS_OUT_SEGMENT_ADD 27
36585 +#define ZEBRA_MPLS_OUT_SEGMENT_DELETE 28
36586 +#define ZEBRA_MPLS_LABELSPACE_ADD 29
36587 +#define ZEBRA_MPLS_LABELSPACE_DELETE 30
36588 +#define ZEBRA_MPLS_FTN_ADD 31
36589 +#define ZEBRA_MPLS_FTN_DELETE 32
36590 +#define ZEBRA_MESSAGE_MAX 33
36592 /* Marker value used in new Zserv, in the byte location corresponding
36593 * the command value in the old zserv header. To allow old and new
36594 @@ -433,7 +448,10 @@
36595 #define ZEBRA_ROUTE_ISIS 8
36596 #define ZEBRA_ROUTE_BGP 9
36597 #define ZEBRA_ROUTE_HSLS 10
36598 -#define ZEBRA_ROUTE_MAX 11
36599 +#define ZEBRA_ROUTE_LDP 11
36600 +#define ZEBRA_ROUTE_RSVP 12
36601 +#define ZEBRA_ROUTE_TE 13
36602 +#define ZEBRA_ROUTE_MAX 14
36604 /* Note: whenever a new route-type or zserv-command is added the
36605 * corresponding {command,route}_types[] table in lib/log.c MUST be
36606 @@ -472,17 +490,29 @@
36607 #define ZEBRA_FLAG_CHANGED 0x20
36608 #define ZEBRA_FLAG_STATIC 0x40
36609 #define ZEBRA_FLAG_REJECT 0x80
36610 +#define ZEBRA_FLAG_CHANGED_MPLS 0x100
36613 + * REJECT and BLACKHOLE flags should never be set by
36614 + * anything except nexthop_active_check(), instead create
36615 + * a nexthop * with flag ZEBRA_NEXTHOP_DROP and set the
36616 + * drop field to one of the ZEBRA_DROP_* values below.
36617 + */
36619 /* Zebra nexthop flags. */
36620 -#define ZEBRA_NEXTHOP_IFINDEX 1
36621 -#define ZEBRA_NEXTHOP_IFNAME 2
36622 -#define ZEBRA_NEXTHOP_IPV4 3
36623 -#define ZEBRA_NEXTHOP_IPV4_IFINDEX 4
36624 -#define ZEBRA_NEXTHOP_IPV4_IFNAME 5
36625 -#define ZEBRA_NEXTHOP_IPV6 6
36626 -#define ZEBRA_NEXTHOP_IPV6_IFINDEX 7
36627 -#define ZEBRA_NEXTHOP_IPV6_IFNAME 8
36628 -#define ZEBRA_NEXTHOP_BLACKHOLE 9
36629 +#define ZEBRA_NEXTHOP_IFINDEX 0x01
36630 +#define ZEBRA_NEXTHOP_IFNAME 0x02
36631 +#define ZEBRA_NEXTHOP_IPV4 0x04
36632 +#define ZEBRA_NEXTHOP_IPV6 0x08
36633 +#define ZEBRA_NEXTHOP_DROP 0x10
36634 +#define ZEBRA_NEXTHOP_SRC_IPV4 0x20
36635 +#define ZEBRA_NEXTHOP_SRC_IPV6 0x40
36636 +#define ZEBRA_NEXTHOP_MPLS 0x80
36637 +#define ZEBRA_NEXTHOP_ALL 0xFF
36639 +#define ZEBRA_DROP_BLACKHOLE 1
36640 +#define ZEBRA_DROP_REJECT 2
36641 +#define ZEBRA_DROP_NULL 3
36643 #ifndef INADDR_LOOPBACK
36644 #define INADDR_LOOPBACK 0x7f000001 /* Internet address 127.0.0.1. */
36645 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/Makefile.am quagga-mpls/Makefile.am
36646 --- quagga/Makefile.am 2007-08-06 10:09:19.000000000 -0500
36647 +++ quagga-mpls/Makefile.am 2008-02-27 23:48:16.000000000 -0600
36648 @@ -2,10 +2,10 @@
36650 SUBDIRS = lib @ZEBRA@ @BGPD@ @RIPD@ @RIPNGD@ @OSPFD@ @OSPF6D@ \
36651 @ISISD@ @WATCHQUAGGA@ @VTYSH@ @OSPFCLIENT@ doc m4 @pkgsrcdir@ \
36652 - redhat @SOLARIS@
36653 + redhat @SOLARIS@ @LDPD@ @RSVPD@
36655 -DIST_SUBDIRS = lib zebra bgpd ripd ripngd ospfd ospf6d \
36656 - isisd watchquagga vtysh ospfclient doc m4 pkgsrc redhat tests \
36657 +DIST_SUBDIRS = lib zebra bgpd ripd ripngd ospfd ospf6d ldpd rsvpd \
36658 + isisd watchquagga vtysh ospfclient ldpd doc m4 pkgsrc redhat tests \
36659 solaris
36661 EXTRA_DIST = aclocal.m4 SERVICES TODO REPORTING-BUGS INSTALL.quagga.txt \
36662 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ospf6d/ospf6_zebra.c quagga-mpls/ospf6d/ospf6_zebra.c
36663 --- quagga/ospf6d/ospf6_zebra.c 2005-10-03 09:20:32.000000000 -0500
36664 +++ quagga-mpls/ospf6d/ospf6_zebra.c 2007-03-26 23:15:02.000000000 -0500
36665 @@ -195,74 +195,50 @@
36666 struct zapi_ipv6 api;
36667 unsigned long ifindex;
36668 struct prefix_ipv6 p;
36669 - struct in6_addr *nexthop;
36670 + struct in6_addr nexthop;
36671 + int i;
36673 s = zclient->ibuf;
36674 - ifindex = 0;
36675 - nexthop = NULL;
36676 memset (&api, 0, sizeof (api));
36678 - /* Type, flags, message. */
36679 - api.type = stream_getc (s);
36680 - api.flags = stream_getc (s);
36681 - api.message = stream_getc (s);
36683 - /* IPv6 prefix. */
36684 - memset (&p, 0, sizeof (struct prefix_ipv6));
36685 - p.family = AF_INET6;
36686 - p.prefixlen = stream_getc (s);
36687 - stream_get (&p.prefix, s, PSIZE (p.prefixlen));
36689 - /* Nexthop, ifindex, distance, metric. */
36690 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
36692 - api.nexthop_num = stream_getc (s);
36693 - nexthop = (struct in6_addr *)
36694 - malloc (api.nexthop_num * sizeof (struct in6_addr));
36695 - stream_get (nexthop, s, api.nexthop_num * sizeof (struct in6_addr));
36697 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
36699 - api.ifindex_num = stream_getc (s);
36700 - ifindex = stream_getl (s);
36702 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
36703 - api.distance = stream_getc (s);
36704 - else
36705 - api.distance = 0;
36706 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
36707 - api.metric = stream_getl (s);
36708 - else
36709 - api.metric = 0;
36710 + zapi_ipv6_read (s, length, &api, &p);
36712 - if (IS_OSPF6_DEBUG_ZEBRA (RECV))
36714 - char prefixstr[128], nexthopstr[128];
36715 - prefix2str ((struct prefix *)&p, prefixstr, sizeof (prefixstr));
36716 - if (nexthop)
36717 - inet_ntop (AF_INET6, nexthop, nexthopstr, sizeof (nexthopstr));
36718 - else
36719 - snprintf (nexthopstr, sizeof (nexthopstr), "::");
36720 + for (i = 0; i < api.nexthop_num; i++)
36721 + {
36722 + ifindex = 0;
36723 + memset (&nexthop, 0, sizeof (nexthop));
36725 - zlog_debug ("Zebra Receive route %s: %s %s nexthop %s ifindex %ld",
36726 - (command == ZEBRA_IPV6_ROUTE_ADD ? "add" : "delete"),
36727 - zebra_route_string(api.type), prefixstr, nexthopstr, ifindex);
36730 - if (command == ZEBRA_IPV6_ROUTE_ADD)
36731 - ospf6_asbr_redistribute_add (api.type, ifindex, (struct prefix *) &p,
36732 - api.nexthop_num, nexthop);
36733 - else
36734 - ospf6_asbr_redistribute_remove (api.type, ifindex, (struct prefix *) &p);
36735 + if (api.nexthop[i].type & ZEBRA_NEXTHOP_IFINDEX)
36736 + ifindex = api.nexthop[i].intf.index;
36738 + if (api.nexthop[i].type & ZEBRA_NEXTHOP_IPV6)
36739 + memcpy(&nexthop, &api.nexthop[i].gw.ipv6, sizeof (nexthop));
36741 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
36742 - free (nexthop);
36743 + if (IS_OSPF6_DEBUG_ZEBRA (RECV))
36745 + char prefixstr[128], nexthopstr[128];
36746 + prefix2str ((struct prefix *)&p, prefixstr, sizeof (prefixstr));
36747 + if (api.nexthop[i].type & ZEBRA_NEXTHOP_IPV6)
36748 + inet_ntop (AF_INET6, &nexthop, nexthopstr, sizeof (nexthopstr));
36749 + else
36750 + snprintf (nexthopstr, sizeof (nexthopstr), "::");
36752 + zlog_debug ("Zebra Receive route %s: %s %s nexthop %s ifindex %ld",
36753 + (command == ZEBRA_IPV6_ROUTE_ADD ? "add" : "delete"),
36754 + zebra_route_string(api.type), prefixstr,
36755 + nexthopstr, ifindex);
36758 + if (command == ZEBRA_IPV6_ROUTE_ADD)
36759 + ospf6_asbr_redistribute_add (api.type, ifindex, (struct prefix *) &p,
36760 + api.nexthop_num, &nexthop);
36761 + else
36762 + ospf6_asbr_redistribute_remove (api.type, ifindex,
36763 + (struct prefix *) &p);
36766 return 0;
36772 DEFUN (show_zebra,
36773 show_zebra_cmd,
36774 @@ -349,8 +325,6 @@
36775 struct zapi_ipv6 api;
36776 char buf[64];
36777 int nhcount;
36778 - struct in6_addr **nexthops;
36779 - unsigned int *ifindexes;
36780 int i, ret = 0;
36781 struct prefix_ipv6 *dest;
36783 @@ -409,24 +383,9 @@
36784 return;
36787 - /* allocate memory for nexthop_list */
36788 - nexthops = XCALLOC (MTYPE_OSPF6_OTHER,
36789 - nhcount * sizeof (struct in6_addr *));
36790 - if (nexthops == NULL)
36792 - zlog_warn ("Can't send route to zebra: malloc failed");
36793 - return;
36796 - /* allocate memory for ifindex_list */
36797 - ifindexes = XCALLOC (MTYPE_OSPF6_OTHER,
36798 - nhcount * sizeof (unsigned int));
36799 - if (ifindexes == NULL)
36801 - zlog_warn ("Can't send route to zebra: malloc failed");
36802 - XFREE (MTYPE_OSPF6_OTHER, nexthops);
36803 - return;
36805 + api.type = ZEBRA_ROUTE_OSPF6;
36806 + api.flags = 0;
36807 + api.message = 0;
36809 for (i = 0; i < nhcount; i++)
36811 @@ -440,19 +399,14 @@
36812 zlog_debug (" nexthop: %s%%%.*s(%d)", buf, IFNAMSIZ, ifname,
36813 request->nexthop[i].ifindex);
36815 - nexthops[i] = &request->nexthop[i].address;
36816 - ifindexes[i] = request->nexthop[i].ifindex;
36818 + SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
36819 + api.nexthop[i].type = ZEBRA_NEXTHOP_IPV6|ZEBRA_NEXTHOP_IFINDEX;
36820 + memcpy (&api.nexthop[i].gw.ipv6, &request->nexthop[i].address, 16);
36821 + api.nexthop[i].intf.index = request->nexthop[i].ifindex;
36824 - api.type = ZEBRA_ROUTE_OSPF6;
36825 - api.flags = 0;
36826 - api.message = 0;
36827 - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
36828 - api.nexthop_num = nhcount;
36829 - api.nexthop = nexthops;
36830 - SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
36831 - api.ifindex_num = nhcount;
36832 - api.ifindex = ifindexes;
36833 + api.nexthop_num = i;
36834 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
36835 api.metric = (request->path.metric_type == 2 ?
36836 request->path.cost_e2 : request->path.cost);
36837 @@ -467,9 +421,6 @@
36838 zlog_err ("zapi_ipv6_route() %s failed: %s",
36839 (type == REM ? "delete" : "add"), safe_strerror (errno));
36841 - XFREE (MTYPE_OSPF6_OTHER, nexthops);
36842 - XFREE (MTYPE_OSPF6_OTHER, ifindexes);
36844 return;
36847 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ospfd/ospf_zebra.c quagga-mpls/ospfd/ospf_zebra.c
36848 --- quagga/ospfd/ospf_zebra.c 2007-03-15 14:14:13.000000000 -0500
36849 +++ quagga-mpls/ospfd/ospf_zebra.c 2008-02-19 22:55:36.000000000 -0600
36850 @@ -339,59 +339,37 @@
36852 u_char message;
36853 u_char distance;
36854 - u_char flags;
36855 - int psize;
36856 - struct stream *s;
36857 struct ospf_path *path;
36858 struct listnode *node;
36859 + struct zapi_ipv4 api;
36860 + int count;
36862 if (zclient->redist[ZEBRA_ROUTE_OSPF])
36864 - message = 0;
36865 - flags = 0;
36867 - /* OSPF pass nexthop and metric */
36868 - SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
36869 - SET_FLAG (message, ZAPI_MESSAGE_METRIC);
36871 - /* Distance value. */
36872 - distance = ospf_distance_apply (p, or);
36873 - if (distance)
36874 - SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
36875 + memset (&api, 0, sizeof (api));
36877 - /* Make packet. */
36878 - s = zclient->obuf;
36879 - stream_reset (s);
36881 - /* Put command, type, flags, message. */
36882 - zclient_create_header (s, ZEBRA_IPV4_ROUTE_ADD);
36883 - stream_putc (s, ZEBRA_ROUTE_OSPF);
36884 - stream_putc (s, flags);
36885 - stream_putc (s, message);
36887 - /* Put prefix information. */
36888 - psize = PSIZE (p->prefixlen);
36889 - stream_putc (s, p->prefixlen);
36890 - stream_write (s, (u_char *) & p->prefix, psize);
36891 + api.flags = 0;
36892 + api.type = ZEBRA_ROUTE_OSPF;
36894 - /* Nexthop count. */
36895 - stream_putc (s, or->paths->count);
36896 + count = 0;
36898 /* Nexthop, ifindex, distance and metric information. */
36899 for (ALL_LIST_ELEMENTS_RO (or->paths, node, path))
36901 if (path->nexthop.s_addr != INADDR_ANY)
36903 - stream_putc (s, ZEBRA_NEXTHOP_IPV4);
36904 - stream_put_in_addr (s, &path->nexthop);
36905 + SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
36906 + api.nexthop[count].type = ZEBRA_NEXTHOP_IPV4;
36907 + api.nexthop[count].gw.ipv4.s_addr = path->nexthop.s_addr;
36909 else
36911 - stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
36912 + SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
36913 + api.nexthop[count].type = ZEBRA_NEXTHOP_IFINDEX;
36914 if (path->oi)
36915 - stream_putl (s, path->oi->ifp->ifindex);
36916 + api.nexthop[count].intf.index = path->oi->ifp->ifindex;
36917 else
36918 - stream_putl (s, 0);
36919 + api.nexthop[count].intf.index = 0;
36922 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
36923 @@ -404,23 +382,29 @@
36924 inet_ntop(AF_INET, &path->nexthop,
36925 buf[1], sizeof(buf[1])));
36927 + count++;
36930 - if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
36931 - stream_putc (s, distance);
36932 - if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
36934 - if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
36935 - stream_putl (s, or->cost + or->u.ext.type2_cost);
36936 - else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
36937 - stream_putl (s, or->u.ext.type2_cost);
36938 - else
36939 - stream_putl (s, or->cost);
36940 + api.nexthop_num = count;
36942 + /* Distance value. */
36943 + distance = ospf_distance_apply (p, or);
36944 + if (distance)
36946 + SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
36947 + api.distance = distance;
36950 - stream_putw_at (s, 0, stream_get_endp (s));
36951 + /* OSPF pass metric */
36952 + SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
36953 + if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
36954 + api.metric = or->cost + or->u.ext.type2_cost;
36955 + else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
36956 + api.metric = or->u.ext.type2_cost;
36957 + else
36958 + api.metric = or->cost;
36960 - zclient_send_message(zclient);
36961 + zapi_ipv4_route(ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api);
36965 @@ -429,31 +413,32 @@
36967 struct zapi_ipv4 api;
36968 struct ospf_path *path;
36969 - struct in_addr *nexthop;
36970 struct listnode *node, *nnode;
36971 + int count;
36973 if (zclient->redist[ZEBRA_ROUTE_OSPF])
36975 api.type = ZEBRA_ROUTE_OSPF;
36976 api.flags = 0;
36977 api.message = 0;
36978 - api.ifindex_num = 0;
36979 - api.nexthop_num = 0;
36980 + count = 0;
36982 for (ALL_LIST_ELEMENTS (or->paths, node, nnode, path))
36984 if (path->nexthop.s_addr != INADDR_ANY)
36986 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
36987 - api.nexthop_num = 1;
36988 - nexthop = &path->nexthop;
36989 - api.nexthop = &nexthop;
36990 + api.nexthop[count].type = ZEBRA_NEXTHOP_IPV4;
36991 + api.nexthop[count].gw.ipv4.s_addr = path->nexthop.s_addr;
36993 else if (ospf_if_exists(path->oi) && (path->oi->ifp))
36995 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
36996 - api.ifindex_num = 1;
36997 - api.ifindex = &path->oi->ifp->ifindex;
36998 + api.nexthop[count].type = ZEBRA_NEXTHOP_IFINDEX;
36999 + if (path->oi)
37000 + api.nexthop[count].intf.index = path->oi->ifp->ifindex;
37001 + else
37002 + api.nexthop[count].intf.index = 0;
37004 else if ( IS_DEBUG_OSPF(zebra,ZEBRA_REDISTRIBUTE) )
37006 @@ -462,24 +447,25 @@
37007 p->prefixlen);
37010 - zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
37012 - if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.nexthop_num)
37013 + if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
37015 char buf[2][INET_ADDRSTRLEN];
37016 - zlog_debug("Zebra: Route delete %s/%d nexthop %s",
37017 - inet_ntop(AF_INET, &p->prefix, buf[0], sizeof(buf[0])),
37018 - p->prefixlen,
37019 - inet_ntop(AF_INET, *api.nexthop,
37020 - buf[1], sizeof(buf[1])));
37022 - if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.ifindex_num)
37024 - zlog_debug ("Zebra: Route delete %s/%d ifindex %d",
37025 - inet_ntoa (p->prefix),
37026 - p->prefixlen, *api.ifindex);
37027 + zlog_debug("Zebra: Route delete %s/%d",
37028 + inet_ntop(AF_INET, &p->prefix, buf[0],
37029 + sizeof(buf[0])), p->prefixlen);
37031 + if (CHECK_FLAG (api.nexthop[count].type, ZEBRA_NEXTHOP_IPV4))
37032 + zlog_debug("\tnexthop %s", inet_ntop(AF_INET,
37033 + &api.nexthop[count].gw.ipv4,
37034 + buf[1], sizeof(buf[1])));
37036 + if (CHECK_FLAG (api.nexthop[count].type, ZEBRA_NEXTHOP_IFINDEX))
37037 + zlog_debug ("\tifindex %d", api.nexthop[count].intf.index);
37039 + count++;
37041 + api.nexthop_num = count;
37042 + zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
37046 @@ -491,11 +477,11 @@
37047 if (zclient->redist[ZEBRA_ROUTE_OSPF])
37049 api.type = ZEBRA_ROUTE_OSPF;
37050 - api.flags = ZEBRA_FLAG_BLACKHOLE;
37051 - api.message = 0;
37052 - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
37053 - api.nexthop_num = 0;
37054 - api.ifindex_num = 0;
37055 + api.flags = 0;
37056 + api.message = ZAPI_MESSAGE_NEXTHOP;
37057 + api.nexthop_num = 1;
37058 + api.nexthop[0].type = ZEBRA_NEXTHOP_DROP;
37059 + api.nexthop[0].gw.drop = ZEBRA_DROP_BLACKHOLE;
37061 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api);
37063 @@ -513,11 +499,11 @@
37064 if (zclient->redist[ZEBRA_ROUTE_OSPF])
37066 api.type = ZEBRA_ROUTE_OSPF;
37067 - api.flags = ZEBRA_FLAG_BLACKHOLE;
37068 - api.message = 0;
37069 - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
37070 - api.nexthop_num = 0;
37071 - api.ifindex_num = 0;
37072 + api.flags = 0;
37073 + api.message = ZAPI_MESSAGE_NEXTHOP;
37074 + api.nexthop_num = 1;
37075 + api.nexthop[0].type = ZEBRA_NEXTHOP_DROP;
37076 + api.nexthop[0].gw.drop = ZEBRA_DROP_BLACKHOLE;
37078 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
37080 @@ -800,96 +786,85 @@
37081 struct prefix_ipv4 p;
37082 struct external_info *ei;
37083 struct ospf *ospf;
37084 + int i;
37086 s = zclient->ibuf;
37087 - ifindex = 0;
37088 - nexthop.s_addr = 0;
37090 - /* Type, flags, message. */
37091 - api.type = stream_getc (s);
37092 - api.flags = stream_getc (s);
37093 - api.message = stream_getc (s);
37095 - /* IPv4 prefix. */
37096 - memset (&p, 0, sizeof (struct prefix_ipv4));
37097 - p.family = AF_INET;
37098 - p.prefixlen = stream_getc (s);
37099 - stream_get (&p.prefix, s, PSIZE (p.prefixlen));
37100 + zapi_ipv4_read (s, length, &api, &p);
37102 if (IPV4_NET127(ntohl(p.prefix.s_addr)))
37103 return 0;
37105 - /* Nexthop, ifindex, distance, metric. */
37106 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
37108 - api.nexthop_num = stream_getc (s);
37109 - nexthop.s_addr = stream_get_ipv4 (s);
37111 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
37113 - api.ifindex_num = stream_getc (s);
37114 - /* XXX assert(api.ifindex_num == 1); */
37115 - ifindex = stream_getl (s);
37117 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
37118 - api.distance = stream_getc (s);
37119 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
37120 - api.metric = stream_getl (s);
37122 ospf = ospf_lookup ();
37123 if (ospf == NULL)
37124 return 0;
37126 - if (command == ZEBRA_IPV4_ROUTE_ADD)
37127 + /* Nexthop, ifindex, distance, metric. */
37128 + if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
37130 - /* XXX|HACK|TODO|FIXME:
37131 - * Maybe we should ignore reject/blackhole routes? Testing shows that
37132 - * there is no problems though and this is only way to "summarize"
37133 - * routes in ASBR at the moment. Maybe we need just a better generalised
37134 - * solution for these types?
37136 - * if ( CHECK_FLAG (api.flags, ZEBRA_FLAG_BLACKHOLE)
37137 - * || CHECK_FLAG (api.flags, ZEBRA_FLAG_REJECT))
37138 - * return 0;
37139 - */
37140 + for (i = 0; i < api.nexthop_num; i++)
37142 + nexthop.s_addr = 0;
37143 + ifindex = 0;
37145 + if (CHECK_FLAG (api.nexthop[i].type, ZEBRA_NEXTHOP_IPV4))
37146 + nexthop.s_addr = api.nexthop[i].gw.ipv4.s_addr;
37148 + if (CHECK_FLAG (api.nexthop[i].type, ZEBRA_NEXTHOP_IFINDEX))
37149 + ifindex = api.nexthop[i].intf.index;
37151 + if (command == ZEBRA_IPV4_ROUTE_ADD)
37153 + /* XXX|HACK|TODO|FIXME:
37154 + * Maybe we should ignore reject/blackhole routes? Testing shows that
37155 + * there is no problems though and this is only way to "summarize"
37156 + * routes in ASBR at the moment. Maybe we need just a better generalised
37157 + * solution for these types?
37159 + * if ( CHECK_FLAG (api.flags, ZEBRA_FLAG_BLACKHOLE)
37160 + * || CHECK_FLAG (api.flags, ZEBRA_FLAG_REJECT))
37161 + * return 0;
37162 + */
37164 - ei = ospf_external_info_add (api.type, p, ifindex, nexthop);
37165 + ei = ospf_external_info_add (api.type, p, ifindex, nexthop);
37167 - if (ospf->router_id.s_addr == 0)
37168 - /* Set flags to generate AS-external-LSA originate event
37169 - for each redistributed protocols later. */
37170 - ospf->external_origin |= (1 << api.type);
37171 - else
37173 - if (ei)
37174 + if (ospf->router_id.s_addr == 0)
37175 + /* Set flags to generate AS-external-LSA originate event
37176 + for each redistributed protocols later. */
37177 + ospf->external_origin |= (1 << api.type);
37178 + else
37180 + if (ei)
37182 + if (is_prefix_default (&p))
37183 + ospf_external_lsa_refresh_default (ospf);
37184 + else
37186 + struct ospf_lsa *current;
37188 + current = ospf_external_info_find_lsa (ospf, &ei->p);
37189 + if (!current)
37190 + ospf_external_lsa_originate (ospf, ei);
37191 + else if (IS_LSA_MAXAGE (current))
37192 + ospf_external_lsa_refresh (ospf, current,
37193 + ei, LSA_REFRESH_FORCE);
37194 + else
37195 + zlog_warn ("ospf_zebra_read_ipv4() : %s already exists",
37196 + inet_ntoa (p.prefix));
37201 + else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
37203 + ospf_external_info_delete (api.type, p);
37204 if (is_prefix_default (&p))
37205 ospf_external_lsa_refresh_default (ospf);
37206 else
37208 - struct ospf_lsa *current;
37210 - current = ospf_external_info_find_lsa (ospf, &ei->p);
37211 - if (!current)
37212 - ospf_external_lsa_originate (ospf, ei);
37213 - else if (IS_LSA_MAXAGE (current))
37214 - ospf_external_lsa_refresh (ospf, current,
37215 - ei, LSA_REFRESH_FORCE);
37216 - else
37217 - zlog_warn ("ospf_zebra_read_ipv4() : %s already exists",
37218 - inet_ntoa (p.prefix));
37220 + ospf_external_lsa_flush (ospf, api.type, &p, ifindex /*, nexthop */);
37224 - else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
37226 - ospf_external_info_delete (api.type, p);
37227 - if (is_prefix_default (&p))
37228 - ospf_external_lsa_refresh_default (ospf);
37229 - else
37230 - ospf_external_lsa_flush (ospf, api.type, &p, ifindex /*, nexthop */);
37233 return 0;
37235 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/redhat/ldpd.init quagga-mpls/redhat/ldpd.init
37236 --- quagga/redhat/ldpd.init 1969-12-31 18:00:00.000000000 -0600
37237 +++ quagga-mpls/redhat/ldpd.init 2006-08-09 22:02:49.000000000 -0500
37238 @@ -0,0 +1,64 @@
37239 +#!/bin/bash
37241 +# chkconfig: 2345 17 83
37242 +# description: An LDP signaling engine for use with Zebra
37244 +# processname: ldpd
37245 +# config: /etc/quagga/ldpd.conf
37247 +# source function library
37248 +. /etc/rc.d/init.d/functions
37250 +# Get network config
37251 +. /etc/sysconfig/network
37253 +# quagga command line options
37254 +. /etc/sysconfig/quagga
37256 +# Check that networking is up.
37257 +[ "${NETWORKING}" = "no" ] && exit 0
37259 +# The process must be configured first.
37260 +[ -f /etc/quagga/ldpd.conf ] || exit 0
37262 +RETVAL=0
37264 +prog="ldpd"
37266 +case "$1" in
37267 + start)
37268 + echo -n $"Starting $prog: "
37269 + daemon /usr/sbin/ldpd -d $LDPD_OPTS
37270 + RETVAL=$?
37271 + [ $RETVAL -eq 0 ] && touch /var/lock/subsys/ldpd
37272 + echo
37273 + ;;
37274 + stop)
37275 + echo -n $"Shutting down $prog: "
37276 + killproc ldpd
37277 + RETVAL=$?
37278 + [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/ldpd
37279 + echo
37280 + ;;
37281 + restart|reload)
37282 + $0 stop
37283 + $0 start
37284 + RETVAL=$?
37285 + ;;
37286 + condrestart)
37287 + if [ -f /var/lock/subsys/ldpd ]; then
37288 + $0 stop
37289 + $0 start
37290 + fi
37291 + RETVAL=$?
37292 + ;;
37293 + status)
37294 + status ldpd
37295 + RETVAL=$?
37296 + ;;
37297 + *)
37298 + echo $"Usage: $0 {start|stop|restart|reload|condrestart|status}"
37299 + exit 1
37300 +esac
37302 +exit $RETVAL
37303 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/redhat/Makefile.am quagga-mpls/redhat/Makefile.am
37304 --- quagga/redhat/Makefile.am 2005-11-04 06:49:11.000000000 -0600
37305 +++ quagga-mpls/redhat/Makefile.am 2006-08-09 22:02:49.000000000 -0500
37306 @@ -1,4 +1,4 @@
37308 EXTRA_DIST = quagga.pam quagga.sysconfig quagga.spec quagga.logrotate \
37309 zebra.init ripd.init ospfd.init ripngd.init ospf6d.init bgpd.init \
37310 - isisd.init watchquagga.init quagga.pam.stack
37311 + isisd.init ldpd.init watchquagga.init quagga.pam.stack
37312 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/redhat/quagga.spec.in quagga-mpls/redhat/quagga.spec.in
37313 --- quagga/redhat/quagga.spec.in 2008-09-04 20:53:12.000000000 -0500
37314 +++ quagga-mpls/redhat/quagga.spec.in 2008-09-07 20:20:11.000000000 -0500
37315 @@ -15,6 +15,7 @@
37316 %{!?with_vtysh: %define with_vtysh 1 }
37317 %{!?with_pam: %define with_pam 1 }
37318 %{!?with_ipv6: %define with_ipv6 1 }
37319 +%{!?with_mpls: %define with_mpls 1 }
37320 %{!?with_ospfclient: %define with_ospfclient 1 }
37321 %{!?with_ospfapi: %define with_ospfapi 1 }
37322 %{!?with_irdp: %define with_irdp 1 }
37323 @@ -79,21 +80,27 @@
37324 %define daemon_other ""
37325 %endif
37327 -%define all_daemons %{daemon_list} %{daemonv6_list} %{daemon_other} watchquagga
37328 +%if %{with_mpls}
37329 +%define daemon_mpls ldpd rsvpd
37330 +%else
37331 +%define daemon_mpls ""
37332 +%endif
37334 +%define all_daemons %{daemon_list} %{daemonv6_list} %{daemon_other} %{daemon_mpls} watchquagga
37336 # allow build dir to be kept
37337 %{!?keep_build: %define keep_build 0 }
37339 -#release sub-revision (the two digits after the CONFDATE)
37340 -%{!?release_rev: %define release_rev 01 }
37341 +#release
37342 +%{!?release_rev: %define release_rev 1 }
37344 Summary: Routing daemon
37345 Name: quagga
37346 Version: @VERSION@
37347 -Release: @CONFDATE@%{release_rev}
37348 +Release: %{release_rev}%{dist}.mpls.%{subver}
37349 License: GPL
37350 Group: System Environment/Daemons
37351 -Source0: http://www.quagga.net/snapshots/cvs/%{name}-%{version}.tar.gz
37352 +Source0: http://www.quagga.net/download/%{name}-%{version}.tar.gz
37353 URL: http://www.quagga.net
37354 %if %{with_snmp}
37355 BuildRequires: net-snmp-devel
37356 @@ -144,7 +151,6 @@
37357 %setup -q
37359 %build
37361 # For standard gcc verbosity, uncomment these lines:
37362 #CFLAGS="%{optflags} -Wall -Wsign-compare -Wpointer-arith"
37363 #CFLAGS="${CFLAGS} -Wbad-function-cast -Wwrite-strings"
37364 @@ -154,6 +160,7 @@
37365 #CFLAGS="${CFLAGS} -Wmissing-declarations -Wmissing-noreturn"
37366 #CFLAGS="${CFLAGS} -Wmissing-format-attribute -Wunreachable-code"
37367 #CFLAGS="${CFLAGS} -Wpacked -Wpadded"
37368 +export CPPFLAGS="-I %{zeb_src}/include ${CPPFLAGS}"
37370 %configure \
37371 %if !%{with_shared}
37372 @@ -162,6 +169,9 @@
37373 %if %{with_ipv6}
37374 --enable-ipv6 \
37375 %endif
37376 +%if %{with_mpls}
37377 + --enable-mpls=%{with_mpls} \
37378 +%endif
37379 %if %{with_snmp}
37380 --enable-snmp \
37381 %endif
37382 @@ -303,6 +313,10 @@
37383 %if %{with_isisd}
37384 zebra_spec_add_service isisd 2608/tcp "ISISd vty"
37385 %endif
37386 +%if %{with_mpls}
37387 +zebra_spec_add_service ldpd 2610/tcp "LDPd vty"
37388 +zebra_spec_add_service rsvpd 2611/tcp "RSVPd vty"
37389 +%endif
37391 for daemon in %daemon_list ; do
37392 /sbin/chkconfig --add ${daemon}
37393 @@ -410,6 +424,10 @@
37394 %if %{with_isisd}
37395 %{_sbindir}/isisd
37396 %endif
37397 +%if %{with_mpls}
37398 +%{_sbindir}/ldpd
37399 +%{_sbindir}/rsvpd
37400 +%endif
37401 %dir %attr(755,root,root) %{_libdir}
37402 %if %{with_shared}
37403 %dir %{_libdir}
37404 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/redhat/quagga.sysconfig quagga-mpls/redhat/quagga.sysconfig
37405 --- quagga/redhat/quagga.sysconfig 2005-01-26 05:21:08.000000000 -0600
37406 +++ quagga-mpls/redhat/quagga.sysconfig 2007-05-14 21:50:00.000000000 -0500
37407 @@ -9,6 +9,7 @@
37408 RIPNGD_OPTS="-A ::1 -f ${QCONFDIR}/ripngd.conf"
37409 ZEBRA_OPTS="-A 127.0.0.1 -f ${QCONFDIR}/zebra.conf"
37410 ISISD_OPTS="-A ::1 -f ${QCONFDIR}/isisd.conf"
37411 +LDPD_OPTS="-A 127.0.0.1 -f ${QCONFDIR}/ldpd.conf"
37413 # Watchquagga configuration (please check timer values before using):
37414 WATCH_OPTS=""
37415 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/redhat/rsvpd.init quagga-mpls/redhat/rsvpd.init
37416 --- quagga/redhat/rsvpd.init 1969-12-31 18:00:00.000000000 -0600
37417 +++ quagga-mpls/redhat/rsvpd.init 2008-02-25 22:06:23.000000000 -0600
37418 @@ -0,0 +1,64 @@
37419 +#!/bin/bash
37421 +# chkconfig: 2345 17 83
37422 +# description: An RSVP signaling engine for use with Zebra
37424 +# processname: rsvpd
37425 +# config: /etc/quagga/rsvpd.conf
37427 +# source function library
37428 +. /etc/rc.d/init.d/functions
37430 +# Get network config
37431 +. /etc/sysconfig/network
37433 +# quagga command line options
37434 +. /etc/sysconfig/quagga
37436 +# Check that networking is up.
37437 +[ "${NETWORKING}" = "no" ] && exit 0
37439 +# The process must be configured first.
37440 +[ -f /etc/quagga/rsvpd.conf ] || exit 0
37442 +RETVAL=0
37444 +prog="rsvpd"
37446 +case "$1" in
37447 + start)
37448 + echo -n $"Starting $prog: "
37449 + daemon /usr/sbin/rsvpd -d $RSVPD_OPTS
37450 + RETVAL=$?
37451 + [ $RETVAL -eq 0 ] && touch /var/lock/subsys/rsvpd
37452 + echo
37453 + ;;
37454 + stop)
37455 + echo -n $"Shutting down $prog: "
37456 + killproc rsvpd
37457 + RETVAL=$?
37458 + [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/rsvpd
37459 + echo
37460 + ;;
37461 + restart|reload)
37462 + $0 stop
37463 + $0 start
37464 + RETVAL=$?
37465 + ;;
37466 + condrestart)
37467 + if [ -f /var/lock/subsys/rsvpd ]; then
37468 + $0 stop
37469 + $0 start
37470 + fi
37471 + RETVAL=$?
37472 + ;;
37473 + status)
37474 + status rsvpd
37475 + RETVAL=$?
37476 + ;;
37477 + *)
37478 + echo $"Usage: $0 {start|stop|restart|reload|condrestart|status}"
37479 + exit 1
37480 +esac
37482 +exit $RETVAL
37483 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ripd/rip_zebra.c quagga-mpls/ripd/rip_zebra.c
37484 --- quagga/ripd/rip_zebra.c 2006-06-30 11:56:18.000000000 -0500
37485 +++ quagga-mpls/ripd/rip_zebra.c 2007-03-26 23:15:02.000000000 -0500
37486 @@ -48,8 +48,8 @@
37487 api.message = 0;
37488 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
37489 api.nexthop_num = 1;
37490 - api.nexthop = &nexthop;
37491 - api.ifindex_num = 0;
37492 + api.nexthop[0].type = ZEBRA_NEXTHOP_IPV4;
37493 + api.nexthop[0].gw.ipv4.s_addr = nexthop->s_addr;
37494 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
37495 api.metric = metric;
37497 @@ -78,8 +78,8 @@
37498 api.message = 0;
37499 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
37500 api.nexthop_num = 1;
37501 - api.nexthop = &nexthop;
37502 - api.ifindex_num = 0;
37503 + api.nexthop[0].type = ZEBRA_NEXTHOP_IPV4;
37504 + api.nexthop[0].gw.ipv4.s_addr = nexthop->s_addr;
37505 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
37506 api.metric = metric;
37508 @@ -98,48 +98,38 @@
37509 unsigned long ifindex;
37510 struct in_addr nexthop;
37511 struct prefix_ipv4 p;
37512 + int i;
37514 s = zclient->ibuf;
37515 - ifindex = 0;
37516 - nexthop.s_addr = 0;
37518 - /* Type, flags, message. */
37519 - api.type = stream_getc (s);
37520 - api.flags = stream_getc (s);
37521 - api.message = stream_getc (s);
37523 - /* IPv4 prefix. */
37524 - memset (&p, 0, sizeof (struct prefix_ipv4));
37525 - p.family = AF_INET;
37526 - p.prefixlen = stream_getc (s);
37527 - stream_get (&p.prefix, s, PSIZE (p.prefixlen));
37528 + zapi_ipv4_read(s, length, &api, &p);
37530 + if (!CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
37531 + api.distance = 255;
37533 /* Nexthop, ifindex, distance, metric. */
37534 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
37536 - api.nexthop_num = stream_getc (s);
37537 - nexthop.s_addr = stream_get_ipv4 (s);
37539 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
37541 - api.ifindex_num = stream_getc (s);
37542 - ifindex = stream_getl (s);
37543 + for (i = 0; i < api.nexthop_num; i++)
37545 + ifindex = 0;
37546 + nexthop.s_addr = 0;
37548 + if (CHECK_FLAG (api.nexthop[i].type, ZEBRA_NEXTHOP_IPV4))
37549 + nexthop.s_addr = api.nexthop[i].gw.ipv4.s_addr;
37551 + if (CHECK_FLAG (api.nexthop[i].type, ZEBRA_NEXTHOP_IFINDEX))
37552 + ifindex = api.nexthop[i].intf.index;
37554 + /* Then fetch IPv4 prefixes. */
37555 + if (command == ZEBRA_IPV4_ROUTE_ADD)
37556 + rip_redistribute_add (api.type, RIP_ROUTE_REDISTRIBUTE, &p,
37557 + ifindex, &nexthop, api.metric, api.distance);
37558 + else
37559 + rip_redistribute_delete (api.type, RIP_ROUTE_REDISTRIBUTE,
37560 + &p, ifindex);
37563 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
37564 - api.distance = stream_getc (s);
37565 - else
37566 - api.distance = 255;
37567 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
37568 - api.metric = stream_getl (s);
37569 - else
37570 - api.metric = 0;
37572 - /* Then fetch IPv4 prefixes. */
37573 - if (command == ZEBRA_IPV4_ROUTE_ADD)
37574 - rip_redistribute_add (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex,
37575 - &nexthop, api.metric, api.distance);
37576 - else
37577 - rip_redistribute_delete (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex);
37579 return 0;
37581 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/ripngd/ripng_zebra.c quagga-mpls/ripngd/ripng_zebra.c
37582 --- quagga/ripngd/ripng_zebra.c 2005-10-03 09:20:35.000000000 -0500
37583 +++ quagga-mpls/ripngd/ripng_zebra.c 2007-03-26 23:15:02.000000000 -0500
37584 @@ -52,13 +52,11 @@
37586 api.type = ZEBRA_ROUTE_RIPNG;
37587 api.flags = 0;
37588 - api.message = 0;
37589 - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
37590 + api.message = ZAPI_MESSAGE_NEXTHOP;
37591 api.nexthop_num = 1;
37592 - api.nexthop = &nexthop;
37593 - SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
37594 - api.ifindex_num = 1;
37595 - api.ifindex = &ifindex;
37596 + api.nexthop[0].type = ZEBRA_NEXTHOP_IPV6|ZEBRA_NEXTHOP_IFINDEX;
37597 + memcpy (&api.nexthop[0].gw.ipv6, nexthop, sizeof (*nexthop));
37598 + api.nexthop[0].intf.index = ifindex;
37599 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
37600 api.metric = metric;
37602 @@ -76,14 +74,12 @@
37604 api.type = ZEBRA_ROUTE_RIPNG;
37605 api.flags = 0;
37606 - api.message = 0;
37607 - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
37608 + api.message = ZAPI_MESSAGE_NEXTHOP;
37609 api.nexthop_num = 1;
37610 - api.nexthop = &nexthop;
37611 - SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
37612 - api.ifindex_num = 1;
37613 - api.ifindex = &ifindex;
37615 + api.nexthop[0].type = ZEBRA_NEXTHOP_IPV6|ZEBRA_NEXTHOP_IFINDEX;
37616 + memcpy (&api.nexthop[0].gw.ipv6, nexthop, sizeof (*nexthop));
37617 + api.nexthop[0].intf.index = ifindex;
37619 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, p, &api);
37622 @@ -98,46 +94,35 @@
37623 unsigned long ifindex;
37624 struct in6_addr nexthop;
37625 struct prefix_ipv6 p;
37626 + int i;
37628 s = zclient->ibuf;
37629 - ifindex = 0;
37630 - memset (&nexthop, 0, sizeof (struct in6_addr));
37632 - /* Type, flags, message. */
37633 - api.type = stream_getc (s);
37634 - api.flags = stream_getc (s);
37635 - api.message = stream_getc (s);
37637 - /* IPv6 prefix. */
37638 - memset (&p, 0, sizeof (struct prefix_ipv6));
37639 - p.family = AF_INET6;
37640 - p.prefixlen = stream_getc (s);
37641 - stream_get (&p.prefix, s, PSIZE (p.prefixlen));
37642 + zapi_ipv6_read (s, length, &api, &p);
37644 /* Nexthop, ifindex, distance, metric. */
37645 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
37647 - api.nexthop_num = stream_getc (s);
37648 - stream_get (&nexthop, s, 16);
37650 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
37652 - api.ifindex_num = stream_getc (s);
37653 - ifindex = stream_getl (s);
37654 + for (i = 0; i < api.nexthop_num; i++)
37656 + ifindex = 0;
37657 + memset (&nexthop, 0, sizeof (struct in6_addr));
37659 + if (CHECK_FLAG (api.nexthop[i].type, ZEBRA_NEXTHOP_IPV4))
37660 + memcpy(&nexthop, &api.nexthop[i].gw.ipv6, sizeof (nexthop));
37662 + if (CHECK_FLAG (api.nexthop[i].type, ZEBRA_NEXTHOP_IFINDEX))
37663 + ifindex = api.nexthop[i].intf.index;
37665 + if (command == ZEBRA_IPV6_ROUTE_ADD)
37666 + ripng_redistribute_add (api.type, RIPNG_ROUTE_REDISTRIBUTE,
37667 + &p, ifindex, &nexthop);
37668 + else
37669 + ripng_redistribute_delete (api.type, RIPNG_ROUTE_REDISTRIBUTE,
37670 + &p, ifindex);
37674 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
37675 - api.distance = stream_getc (s);
37676 - else
37677 - api.distance = 0;
37678 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
37679 - api.metric = stream_getl (s);
37680 - else
37681 - api.metric = 0;
37683 - if (command == ZEBRA_IPV6_ROUTE_ADD)
37684 - ripng_redistribute_add (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex, &nexthop);
37685 - else
37686 - ripng_redistribute_delete (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex);
37688 return 0;
37690 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/general.h quagga-mpls/rsvpd/general.h
37691 --- quagga/rsvpd/general.h 1969-12-31 18:00:00.000000000 -0600
37692 +++ quagga-mpls/rsvpd/general.h 2007-06-14 21:35:58.000000000 -0500
37693 @@ -0,0 +1,41 @@
37695 +#ifndef __GENERAL_H__
37696 +#define __GENERAL_H__
37698 +typedef unsigned long HANDLE;
37700 +typedef unsigned char BOOL;
37702 +typedef unsigned char uns8;
37703 +typedef unsigned short uns16;
37704 +typedef unsigned int uns32;
37706 +#define FALSE 0
37707 +#define TRUE 1
37709 +typedef unsigned int IPV4_ADDR;
37710 +typedef struct
37712 + IPV4_ADDR IpAddr;
37713 + uns8 PrefixLength;
37714 + uns8 Loose;
37715 +} ER_HOP;
37717 +typedef enum
37719 + E_OK,
37720 + E_ERR
37721 +} E_RC;
37724 +#define LOCAL_ADDRESS "127.0.0.1"
37725 +#define RSVP_CONSOLE_PORT 2002
37726 +#define RSVP_TE_PORT 2003
37727 +#define TE_SIM_PORT 2004
37728 +#define TE_APP_PORT 2004
37729 +#define TE_APP_PORT2 2012
37730 +#define TE_APP_PORT3 2013
37731 +#define TE_APP_CONSOLE_PORT 2011
37732 +#define HAS_TE_SIM 1
37734 +#endif
37735 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/Makefile.am quagga-mpls/rsvpd/Makefile.am
37736 --- quagga/rsvpd/Makefile.am 1969-12-31 18:00:00.000000000 -0600
37737 +++ quagga-mpls/rsvpd/Makefile.am 2007-07-03 00:42:53.000000000 -0500
37738 @@ -0,0 +1,34 @@
37739 +## Process this file with automake to produce Makefile.in.
37741 +INCLUDES = @INCLUDES@ -I.. -I$(top_srcdir) -I$(top_srcdir)/lib @SNMP_INCLUDES@
37742 +DEFS = @DEFS@ $(LOCAL_OPTS) -DSYSCONFDIR=\"$(sysconfdir)/\"
37743 +INSTALL_SDATA=@INSTALL@ -m 600
37745 +sbin_PROGRAMS = rsvpd
37747 +rsvpd_SOURCES = rsvp_main.c \
37748 + rsvp_decode.c rsvp_path.c rsvp_utilities.c \
37749 + rsvp_encode.c rsvp_resv.c rsvp_vty.c \
37750 + rsvp_socket.c rsvp_zebra.c rsvp_api.c \
37751 + te_api.c te_bw_man.c te_common.c \
37752 + te_lib.c te_crr.c te_lsp.c \
37753 + te_rdb.c te_tr.c \
37754 + patricia.c messages.c
37756 +rsvpdheaderdir = $(pkgincludedir)/rsvpd
37758 +noinst_HEADERS =
37759 + rsvp_encode.h rsvp_socket.h rsvp.h te_lib.h \
37760 + rsvp_api.h rsvp_packet.h rsvp_utilities.h \
37761 + rsvp_psb.h rsvp_vty.h rsvp_decode.h rsvp_rsb.h \
37762 + rsvp_zebra.h \
37763 + general.h messages.h patricia.h \
37764 + te_api.h te_bw_man.h te_common.h te_crr.h te_cspf.h \
37765 + te_frr.h te.h te_lsp.h te_rdb.h te_tr.h
37767 +rsvpd_LDADD = ../lib/libzebra.la @LIBCAP@
37769 +EXTRA_DIST =
37771 +examplesdir = $(exampledir)
37772 +dist_examples_DATA =
37773 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/messages.c quagga-mpls/rsvpd/messages.c
37774 --- quagga/rsvpd/messages.c 1969-12-31 18:00:00.000000000 -0600
37775 +++ quagga-mpls/rsvpd/messages.c 2007-07-02 23:22:44.000000000 -0500
37776 @@ -0,0 +1,353 @@
37777 +#include <zebra.h>
37778 +#include <stdlib.h>
37780 +#include "general.h"
37781 +#include "thread.h"
37782 +#include "workqueue.h"
37783 +#include "memory.h"
37784 +#include "log.h"
37786 +#include "rsvp.h"
37787 +#include "te.h"
37789 +struct mesg_block
37791 + void *data;
37792 + int size;
37795 +extern struct thread_master *master;
37797 +static struct work_queue *rsvp2te = NULL;
37798 +static struct work_queue *te2rsvp = NULL;
37799 +static struct work_queue *te2te = NULL;
37801 +static int
37802 +RSVP_ProcessTeMsg (void *data, int Length)
37804 + TE_API_MSG Msg, *pMsg = data;
37805 + int ret = 0;
37807 + switch (pMsg->NotificationType)
37809 + case PATH_MSG_NOTIFICATION:
37810 + ret = ProcessTEMsgUponPath (pMsg);
37811 + break;
37812 + case RESV_MSG_NOTIFICATION:
37813 + ret = ResvTeMsgProc (pMsg);
37814 + break;
37815 + case PATH_SEND_CMD:
37816 + RsvpPathSendCmd (pMsg);
37817 + break;
37818 + case PATH_TEAR_CMD:
37819 + RsvpPathTearCmd (pMsg);
37820 + break;
37821 + case PREEMPT_FLOW_CMD:
37822 + PreemptFlow (pMsg);
37823 + break;
37824 + case DEBUG_SEND_RESV_TEAR_CMD:
37825 + ret = DebugSendResvTear (pMsg);
37826 + break;
37827 + default:
37828 + printf ("TE-->RSVP: unknown message type %d %s %d\n",
37829 + pMsg->NotificationType, __FILE__, __LINE__);
37831 + return ret;
37834 +static int
37835 +TE_ProcessTeMsg (void *data, int Len)
37837 + void *pBuf = data;
37838 + EVENTS_E *pEvent = data;
37839 + TE_MSG *pMsg;
37841 + switch (*pEvent)
37843 + case EVENT_TE_SM:
37844 + pMsg = pBuf;
37845 + sm_call (pMsg->u.te_sm_event.data);
37846 + break;
37847 + case EVENT_CREATE_TE_PATH:
37848 + TE_IGP_API_PathAdd (pBuf, Len);
37849 + break;
37850 + case EVENT_READ_PATH_CASH:
37851 + TE_IGP_API_ReadPathCash (pBuf, Len);
37852 + break;
37853 +#if FRR_SM_DEFINED
37854 + case EVENT_RRO_CHANGED:
37855 + RRO_ChangedMsg (&dmsg->u.rro_changed_hook);
37856 + break;
37857 + case EVENT_BYPASS_TUNNEL_RETRY_EXPIRY:
37858 + BypassTunnelRetryExpiry (dmsg);
37859 + break;
37860 + case EVENT_FRR_INFO_SET:
37861 + SetFrrData (dmsg);
37862 + break;
37863 +#endif
37864 + default:
37865 + zlog_err ("\nBUG: Default case %s %d", __FILE__, __LINE__);
37869 +static int
37870 +TE_ProcessRsvpMsg (void *data, int Len)
37872 + TE_API_MSG *pTeApiMsg = data;
37873 + char *buffer = data;
37875 + switch (pTeApiMsg->NotificationType)
37877 + case PATH_MSG_NOTIFICATION:
37878 + TE_RSVPTE_API_TransitReqAPI (pTeApiMsg);
37879 + break;
37880 + case RESV_MSG_NOTIFICATION:
37881 + if (pTeApiMsg->u.ResvNotification.Ingress)
37883 + PSB_KEY key;
37884 + float MaximumPossibleBW = 0;
37885 + memset (&key, 0, sizeof (PSB_KEY));
37886 + key.Session = pTeApiMsg->u.ResvNotification.RsbKey.Session;
37887 + if (pTeApiMsg->u.ResvNotification.SharedExplicit)
37889 + if (TE_RSVPTE_API_DoAllocation (&key,
37890 + pTeApiMsg->u.ResvNotification.u.
37891 + FilterDataSE.
37892 + IfIndex /* temporary */ ,
37893 + pTeApiMsg->u.ResvNotification.u.
37894 + FilterDataSE.IfIndex,
37895 + pTeApiMsg->u.ResvNotification.u.
37896 + FilterDataSE.BW,
37897 + pTeApiMsg->u.ResvNotification.u.
37898 + FilterDataSE.SetupPrio,
37899 + pTeApiMsg->u.ResvNotification.u.
37900 + FilterDataSE.HoldPrio,
37901 + &MaximumPossibleBW) != E_OK)
37903 + zlog_info ("\nBW allocation failed %s %d", __FILE__,
37904 + __LINE__);
37905 + pTeApiMsg->u.ResvNotification.u.FilterDataSE.BW =
37906 + MaximumPossibleBW;
37907 + pTeApiMsg->u.ResvNotification.rc = FALSE;
37909 + else
37911 + pTeApiMsg->u.ResvNotification.rc = TRUE;
37912 + TE_RSVPTE_API_RsvpTunnelEstablished (&pTeApiMsg->u.
37913 + ResvNotification);
37916 + else
37918 + key.SenderTemplate =
37919 + pTeApiMsg->u.ResvNotification.u.FilterDataFF.FilterSpec;
37920 + if (TE_RSVPTE_API_DoAllocation
37921 + (&key,
37922 + pTeApiMsg->u.ResvNotification.u.FilterDataFF.
37923 + IfIndex /* temporary */ ,
37924 + pTeApiMsg->u.ResvNotification.u.FilterDataFF.IfIndex,
37925 + pTeApiMsg->u.ResvNotification.u.FilterDataFF.BW,
37926 + pTeApiMsg->u.ResvNotification.u.FilterDataFF.SetupPrio,
37927 + pTeApiMsg->u.ResvNotification.u.FilterDataFF.HoldPrio,
37928 + &MaximumPossibleBW) != E_OK)
37930 + zlog_info ("\nBW allocation failed %s %d", __FILE__,
37931 + __LINE__);
37932 + pTeApiMsg->u.ResvNotification.u.FilterDataFF.BW =
37933 + MaximumPossibleBW;
37934 + pTeApiMsg->u.ResvNotification.rc = FALSE;
37936 + else
37938 + pTeApiMsg->u.ResvNotification.rc = TRUE;
37939 + TE_RSVPTE_API_RsvpTunnelEstablished (&pTeApiMsg->u.
37940 + ResvNotification);
37944 + if (pTeApiMsg->u.ResvNotification.PleaseReply)
37946 + te_send_msg (pTeApiMsg, sizeof (TE_API_MSG));
37949 + else
37950 + TE_RSVPTE_API_TransitResv (pTeApiMsg);
37951 + break;
37952 + case BW_RELEASE_NOTIFICATION:
37953 + TE_RSVPTE_API_BwReleaseMessage (pTeApiMsg);
37954 + break;
37955 + case LABEL_RELEASE_NOTIFICATION:
37956 + TE_RSVPTE_API_LabelRelease (pTeApiMsg);
37957 + break;
37958 + case RESV_TEAR_NOTIFICATION:
37959 + TE_RSVPTE_API_RsvpResvTear (&pTeApiMsg->u.ResvTearNotification);
37960 + break;
37961 + case PATH_ERR_NOTIFICATION:
37962 + TE_RSVPTE_API_RsvpPathErr (&pTeApiMsg->u.PathErrNotification);
37963 + break;
37964 + default:
37965 + zlog_err ("\ndefault case (%d) reached %s %d",
37966 + pTeApiMsg->NotificationType, __FILE__, __LINE__);
37968 + int i;
37969 + for (i = 0; i < 40; i++)
37971 + if (!(i % 8))
37973 + zlog_info ("\n");
37975 + zlog_info ("%x ", buffer[i]);
37979 + return 0;
37982 +void
37983 +SetFrrData (TE_MSG * pMsg)
37985 +#if 0
37986 + PSB_KEY psb_key;
37987 + PSB *pUpPsb;
37989 + memset (&psb_key, '\0', sizeof (psb_key));
37990 + psb_key.Session.Dest = htonl (pMsg->u.frr_data_set.PsbKey.Session.Dest);
37991 + psb_key.Session.TunnelId = pMsg->u.frr_data_set.PsbKey.Session.TunnelId;
37992 + psb_key.Session.ExtTunelId = pMsg->u.frr_data_set.PsbKey.Session.ExtTunelId;
37993 + psb_key.SenderTemplate.LspId =
37994 + pMsg->u.frr_data_set.PsbKey.SenderTemplate.LspId;
37995 + psb_key.SenderTemplate.IpAddr =
37996 + pMsg->u.frr_data_set.PsbKey.SenderTemplate.IpAddr;
37998 + if ((pUpPsb =
37999 + (RSVP_UP_PSB *) patricia_tree_getnext (&intf->info.lms.UpPsbToIntfTree,
38000 + (const uns8 *) &psb_key)) !=
38001 + NULL)
38003 + zlog_info ("\nsetting FRR data %x %x %x for %x %x %x %x %x on IF#%x",
38004 + pMsg->u.frr_data_set.BackupOutIf,
38005 + pMsg->u.frr_data_set.BackupVcardId,
38006 + pMsg->u.frr_data_set.MergeNodeIp,
38007 + psb_key.Session.Dest,
38008 + psb_key.Session.TunnelId,
38009 + psb_key.Session.ExtTunelId,
38010 + psb_key.SenderTemplate.LspId,
38011 + psb_key.SenderTemplate.IpAddr, pMsg->u.frr_data_set.IfIndex);
38012 + /* set here the FRR data */
38014 + else
38016 + zlog_info ("\ncannot find PSB by key %x %x %x %x %x %s %d",
38017 + psb_key.Session.Dest,
38018 + psb_key.Session.TunnelId,
38019 + psb_key.Session.ExtTunelId,
38020 + psb_key.SenderTemplate.LspId,
38021 + psb_key.SenderTemplate.IpAddr, __FILE__, __LINE__);
38023 +#endif
38026 +static wq_item_status
38027 +rsvp_te_process (struct work_queue *wq, void *data)
38029 + struct mesg_block *blk = data;
38030 + TE_ProcessRsvpMsg(blk->data, blk->size);
38031 + XFREE (MTYPE_TMP, data);
38032 + return WQ_SUCCESS;
38035 +static wq_item_status
38036 +te_rsvp_process (struct work_queue *wq, void *data)
38038 + struct mesg_block *blk = data;
38039 + RSVP_ProcessTeMsg(blk->data, blk->size);
38040 + XFREE (MTYPE_TMP, data);
38041 + return WQ_SUCCESS;
38044 +static wq_item_status
38045 +te_te_process (struct work_queue *wq, void *data)
38047 + struct mesg_block *blk = data;
38048 + TE_ProcessTeMsg(blk->data, blk->size);
38049 + XFREE (MTYPE_TMP, data);
38050 + return WQ_SUCCESS;
38053 +void
38054 +rsvp_te_comm_init()
38056 + if (! (rsvp2te = work_queue_new (master, "rsvp->te mesg passing")))
38058 + zlog_err ("%s: could not initialise work queue!", __func__);
38059 + return;
38062 + if (! (te2rsvp = work_queue_new (master, "te->rsvp mesg passing")))
38064 + zlog_err ("%s: could not initialise work queue!", __func__);
38065 + return;
38068 + if (! (te2te = work_queue_new (master, "te->te mesg passing")))
38070 + zlog_err ("%s: could not initialise work queue!", __func__);
38071 + return;
38074 + rsvp2te->spec.workfunc = &rsvp_te_process;
38075 + rsvp2te->spec.errorfunc = NULL;
38076 + rsvp2te->spec.max_retries = 3;
38077 + rsvp2te->spec.hold = 1;
38079 + te2rsvp->spec.workfunc = &te_rsvp_process;
38080 + te2rsvp->spec.errorfunc = NULL;
38081 + te2rsvp->spec.max_retries = 3;
38082 + te2rsvp->spec.hold = 1;
38084 + te2te->spec.workfunc = &te_te_process;
38085 + te2te->spec.errorfunc = NULL;
38086 + te2te->spec.max_retries = 3;
38087 + te2te->spec.hold = 1;
38089 + return;
38092 +E_RC
38093 +rsvp_send_msg (void *pMsg, int size)
38095 + struct mesg_block *blk = NULL;
38096 + blk = XMALLOC (MTYPE_TMP, sizeof(struct mesg_block) + size);
38097 + blk->data = &blk[1];
38098 + blk->size = size;
38099 + memcpy(blk->data, pMsg, size);
38101 + work_queue_add (rsvp2te, blk);
38102 + return E_OK;
38105 +E_RC
38106 +te_send_msg (void *pMsg, int size)
38108 + struct mesg_block *blk = NULL;
38109 + blk = XMALLOC (MTYPE_TMP, sizeof(struct mesg_block) + size);
38110 + blk->data = &blk[1];
38111 + blk->size = size;
38112 + memcpy(blk->data, pMsg, size);
38114 + work_queue_add (te2rsvp, blk);
38115 + return E_OK;
38118 +E_RC
38119 +te2te_send_msg (void *pMsg, int size)
38121 + struct mesg_block *blk = NULL;
38122 + blk = XMALLOC (MTYPE_TMP, sizeof(struct mesg_block) + size);
38123 + blk->data = &blk[1];
38124 + blk->size = size;
38125 + memcpy(blk->data, pMsg, size);
38127 + work_queue_add (te2te, blk);
38128 + return E_OK;
38130 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/messages.h quagga-mpls/rsvpd/messages.h
38131 --- quagga/rsvpd/messages.h 1969-12-31 18:00:00.000000000 -0600
38132 +++ quagga-mpls/rsvpd/messages.h 2008-02-24 00:42:46.000000000 -0600
38133 @@ -0,0 +1,712 @@
38134 +#ifndef _RSVP_API_STRUCT_H_
38135 +#define _RSVP_API_STRUCT_H_
38137 +#include "rsvp_packet.h"
38139 +typedef struct
38141 + SESSION_OBJ Session;
38142 + SENDER_TEMPLATE_OBJ SenderTemplate;
38143 +} PSB_KEY;
38145 +typedef struct
38147 + SESSION_OBJ Session;
38148 +} RSB_KEY;
38150 +#define TE_PATH_RESPONSE 1
38151 +#define TE_RESV_RESPONSE 2
38153 +typedef enum
38155 + PATH_MSG_NOTIFICATION,
38156 + RESV_MSG_NOTIFICATION,
38157 + PATH_ERR_NOTIFICATION,
38158 + RESV_TEAR_NOTIFICATION,
38159 + RRO_CHANGED_NOTIFICATION,
38160 + LABEL_RELEASE_NOTIFICATION,
38161 + BW_RELEASE_NOTIFICATION,
38162 + PREEMPT_FLOW_CMD,
38163 + ENABLE_RSVP_ON_IF,
38164 + DISABLE_RSVP_ON_IF,
38165 + SET_PEER,
38166 + IP_ADDR_ADD,
38167 + IP_ADDR_DEL,
38168 + PATH_SEND_CMD,
38169 + PATH_TEAR_CMD,
38170 + DEBUG_SEND_RESV_TEAR_CMD
38171 +} TE_NOTIFICATION_E;
38173 +typedef enum
38175 + PATH_PROC_OK,
38176 + BW_UNAVAIL,
38177 + NO_ROUTE,
38178 + LABEL_ALLOC_FAILURE,
38179 + UNSUP_L3PID
38180 +} PATH_PROC_E;
38183 +typedef struct
38185 + PSB_KEY PsbKey;
38186 + /* resource affinity info valid, if set to 1 */
38187 + uns8 RA_Valid;
38188 + uns32 ExcludeAny;
38189 + uns32 IncludeAll;
38190 + uns32 IncludeAny;
38191 + /* set to default if received PATH does not contain SESSION_ATTRIBUTES */
38192 + uns8 HoldPrio;
38193 + /* set to default if received PATH does not contain SESSION_ATTRIBUTES */
38194 + uns8 SetupPrio;
38195 + /* RSVP-TE -> TE-APP: received ER HOPS, TE-APP -> RSVP-TE - inserted ER HOPS */
38196 + /*(if first - loose, before first, otherwise - after the last */
38197 + uns16 ErHopNumber;
38198 + /* if set to 1 - first ER HOP is strict */
38199 + uns8 FirstErHopStrict;
38200 + IPV4_ADDR ErHops[100];
38201 + /* if set to 1, local protection desired */
38202 + uns8 LocalProtection;
38203 + /* shared explicit style, if set to 1 */
38204 + uns8 SharedExplicit;
38205 + /* allocated label */
38206 + uns32 Label;
38207 + /* requested BW */
38208 + float BW;
38209 + /* TE output - OutIfIndex and Next Hop */
38210 + uns32 OutIfIndex;
38211 + IPV4_ADDR NextHop;
38212 + uns8 LabelRecordingDesired;
38213 + PATH_PROC_E rc;
38214 +} PATH_NOTIFICATION;
38216 +typedef struct
38218 + FILTER_SPEC_OBJ FilterSpec;
38220 + uns32 IfIndex; /* where BW should be allocated. */
38221 + /* extracted from PSB */
38222 + uns8 HoldPrio;
38223 + /* extracted from PSB */
38224 + uns8 SetupPrio;
38225 + /* received label */
38226 + uns32 ReceivedLabel;
38227 + /* allocated label */
38228 + uns32 AllocatedLabel;
38229 + /* requested BW */
38230 + float BW; /* could be different for each FILTER_SPEC if FF, same for each FILTER_SPEC if SE */
38231 +} FILTER_DATA_FF;
38233 +typedef struct
38235 + FILTER_SPEC_OBJ FilterSpec;
38236 + /* received label */
38237 + uns32 ReceivedLabel;
38238 + /* allocated label */
38239 + uns32 AllocatedLabel;
38240 +} FILTER_DATA_ARRAY_SE;
38242 +typedef struct
38244 + /* requested BW */
38245 + float BW; /* could be different for each FILTER_SPEC if FF, same for each FILTER_SPEC if SE */
38246 + /* extracted from PSB */
38247 + uns8 HoldPrio;
38248 + /* extracted from PSB */
38249 + uns8 SetupPrio;
38250 + /* Where to allocate */
38251 + uns32 IfIndex;
38252 + uns16 FilterSpecNumber;
38253 + FILTER_DATA_ARRAY_SE FilterDataArraySE[100];
38254 +} FILTER_DATA_SE;
38256 +typedef struct
38258 + RSB_KEY RsbKey;
38259 + /* If set, Ingress is reached */
38260 + uns8 Ingress;
38261 + uns8 PleaseReply;
38262 + uns8 rc; /* FALSE or TRUE */
38263 + /* if set to 1, shared explicit reservation style */
38264 + uns8 SharedExplicit;
38266 + union
38268 + FILTER_DATA_SE FilterDataSE;
38269 + FILTER_DATA_FF FilterDataFF;
38270 + } u;
38271 +} RESV_NOTIFICATION;
38274 +typedef struct
38276 + RSB_KEY RsbKey;
38277 + uns16 FilterSpecNumber;
38278 + FILTER_SPEC_OBJ FilterSpecs[100];
38279 +} DEBUG_SEND_RESV_TEAR;
38281 +typedef struct
38283 + PSB_KEY PsbKey;
38284 + uns32 Label;
38285 +} LABEL_RELEASE;
38287 +typedef struct
38289 + PSB_KEY PsbKey;
38290 + uns32 IfIndex;
38291 + uns8 HoldPrio;
38292 +} BW_RELEASE;
38294 +typedef struct
38296 + RSB_KEY RsbKey;
38297 + FILTER_SPEC_OBJ FilterSpec;
38298 +} RESV_TEAR_NOTIF;
38300 +typedef struct
38302 + PSB_KEY PsbKey;
38303 + ERR_SPEC_OBJ ErrSpec;
38304 +} PATH_ERR_NOTIF;
38306 +typedef struct
38308 + RSB_KEY RsbKey;
38309 + uns8 FilterSpecValid;
38310 + FILTER_SPEC_OBJ FilterSpec;
38311 +} PREEMPT_FLOW;
38313 +typedef struct
38315 + uns32 IfIndex;
38316 +} IF_CMD;
38318 +typedef struct
38320 + char IfName[20];
38321 + IPV4_ADDR PeerAddr;
38322 +} SET_PEER_CMD;
38324 +typedef struct
38326 + IPV4_ADDR IpAddress;
38327 + uns8 PrefixLen;
38328 + uns32 IfIndex;
38329 +} IP_ADDR_ADD_DEL_CMD;
38331 +typedef struct
38333 + IPV4_ADDR Egress;
38334 + uns16 TunnelId;
38335 + uns16 LspId;
38336 + uns8 RaValid;
38337 + uns32 ExcludeAny;
38338 + uns32 IncludeAny;
38339 + uns32 IncludeAll;
38340 + uns8 HoldPrio;
38341 + uns8 SetPrio;
38342 + uns8 Shared;
38343 + uns8 FrrDesired;
38344 + uns8 LabelRecordingDesired;
38345 + uns16 HopNum;
38346 + ER_HOP Path[100];
38347 + float BW;
38348 + IPV4_ADDR NextHop;
38349 + uns32 OutIfIndex;
38350 + IPV4_ADDR src_ip;
38351 + uns32 sm_handle;
38352 + IPV4_ADDR ErHops2Exclude[10];
38353 +} INGRESS_API;
38355 +typedef struct _te_api_msg_
38357 + TE_NOTIFICATION_E NotificationType;
38358 + union
38360 + PATH_NOTIFICATION PathNotification;
38361 + RESV_NOTIFICATION ResvNotification;
38362 + LABEL_RELEASE LabelRelease;
38363 + BW_RELEASE BwRelease;
38364 + RESV_TEAR_NOTIF ResvTearNotification;
38365 + PATH_ERR_NOTIF PathErrNotification;
38366 + PREEMPT_FLOW PreemptFlow;
38367 + IF_CMD IfCmd;
38368 + SET_PEER_CMD SetPeer;
38369 + IP_ADDR_ADD_DEL_CMD IpAddrAddDel;
38370 + INGRESS_API IngressApi;
38371 + DEBUG_SEND_RESV_TEAR DebugSendResvTear;
38372 + } u;
38373 +} TE_API_MSG;
38375 +#endif
38376 +#ifndef __LIB_API_MSG_H_
38377 +#define __LIB_API_MSG_H_
38379 +void rsvp_te_comm_init ();
38380 +E_RC rsvp_send_msg (void *pBuf, int pSize);
38381 +E_RC te_send_msg (void *pBuf, int pSize);
38383 +#endif
38385 +#ifndef __TE_API_STRUCT_H__
38386 +#define __TE_API_STRUCT_H__
38388 +#include "thread.h"
38390 +#define LSP_NAME_TYPE 1
38391 +#define LSP_DEST_TYPE 2
38392 +#define LSP_SRC_TYPE 3
38393 +#define LSP_REMOVE_TYPE 4
38394 +#define ADAPTIVITY_TYPE 5
38395 +#define BW_TYPE 6
38396 +#define COS_TYPE 7
38397 +#define HOP_LIMIT_TYPE 8
38398 +#define OPTIMIZE_TIMER_TYPE 9
38399 +#define PREFERENCE_TYPE 10
38400 +#define PRIO_TYPE 11
38401 +#define RECORD_TYPE 12
38402 +#define STANDBY_TYPE 13
38403 +#define FRR_TYPE 14
38404 +#define METRIC_TYPE 15
38405 +#define NO_DECREMENT_TTL_TYPE 16
38406 +#define BW_POLICY_TYPE 17
38407 +#define RETRY_TIMER_TYPE 18
38408 +#define RETRY_LIMIT_TYPE 19
38409 +#define PRIMARY_PATH_NAME_TYPE 20
38410 +#define SECONDARY_PATH_NAME_TYPE 21
38411 +#define EXPLICIT_PATH_NAME 22
38412 +#define NH_INDEX 23
38413 +#define NH_LOOSE 24
38414 +#define NH_IP_ADDRESS 25
38415 +#define NO_FORM 26
38416 +#define AFFINITY_TYPE 27
38418 +typedef struct
38420 + int Type;
38421 + int Length;
38422 +} TL_HEADER;
38424 +typedef struct
38426 + TL_HEADER tl_header;
38427 + char data[1];
38428 +} TLV;
38430 +typedef enum
38432 + EVENT_NEXT_HOP_ADD,
38433 + EVENT_NEXT_HOP_DEL,
38434 + EVENT_NEXT_HOP_DUMP,
38435 + EVENT_TE_LINK_ADD,
38436 + EVENT_TE_LINK_DEL,
38437 + EVENT_TE_LINK_STATUS_CHANGE,
38438 + EVENT_TE_LINK_DUMP,
38439 + EVENT_CREATE_TE_PATH,
38440 + EVENT_REMOTE_LS_UPDATE,
38441 + EVENT_CONNECTIVITY_BROKEN,
38442 + EVENT_OPEN_RSVP_LSP,
38443 + EVENT_LSP_USER_SETUP,
38444 + EVENT_CLOSE_RSVP_LSP,
38445 + EVENT_ADD_IF_ADDR,
38446 + EVENT_ENABLE_RSVP,
38447 + EVENT_DISABLE_RSVP,
38448 + EVENT_TE_LOG_CFG,
38449 + EVENT_RSVP_LOG_CFG,
38450 + EVENT_TE_SM,
38451 + EVENT_RRO_CHANGED,
38452 + EVENT_FRR_INFO_SET,
38453 + EVENT_SET_ROUTER_ID,
38454 + EVENT_READ_PATH_CASH,
38455 + EVENT_CSPF_RETRY_EXPIRY,
38456 + EVENT_LINK_2_RTR_ID_MAPPING,
38457 + EVENT_LINK_2_RTR_ID_WITHDRAW,
38458 + EVENT_IGP_HELLO,
38459 + EVENT_DEL_IF_ADDR,
38460 + EVENT_MAX = EVENT_DEL_IF_ADDR
38461 +} EVENTS_E;
38463 +typedef struct
38465 + uns32 IfIndex;
38466 + uns32 BackupOutIf;
38467 +// V_CARD_ID BackupVcardId;
38468 + IPV4_ADDR MergeNodeIp;
38469 + PSB_KEY PsbKey;
38470 +} FRR_DATA_SET;
38472 +typedef struct
38474 + PSB_KEY PsbKey;
38475 + uns32 IfIndex;
38476 +} BUMP_TUNNEL_T;
38478 +typedef struct
38480 + IPV4_ADDR merge_node;
38481 + uns32 OutIfIndex;
38482 + IPV4_ADDR protected_node;
38483 + IPV4_ADDR prohibited_penultimate_node;
38484 +} FRR_SM_KEY;
38486 +typedef struct _tunnel_id_list_
38488 + IPV4_ADDR dest;
38489 + uns16 tunnel_id;
38490 + IPV4_ADDR source;
38491 + struct _tunnel_id_list_ *next;
38492 +} TUNNEL_ID_LIST;
38494 +typedef struct _lsp_path_shared_params_
38496 + BOOL disable;
38497 + float BW;
38498 + uns32 class_of_service;
38499 + uns32 affinity_properties;
38500 + uns32 affinity_mask;
38501 + uns32 hop_limit;
38502 + uns32 optimize_timer;
38503 + uns32 preference;
38504 + uns8 setup_priority;
38505 + uns8 hold_priority;
38506 + BOOL record;
38507 + BOOL standby;
38508 +} LSP_PATH_SHARED_PARAMS;
38510 +typedef struct
38512 + float BW;
38513 + uns32 hop_limit;
38514 + /* admin group */
38515 +} FAST_REROUTE;
38517 +typedef struct _secondary_path_list_
38519 + char Secondary[16];
38520 + LSP_PATH_SHARED_PARAMS *SecondaryPathParams;
38521 + struct _secondary_path_list_ *next;
38522 +} SECONDARY_PATH_LIST;
38524 +typedef struct
38526 + char LspName[32];
38527 + IPV4_ADDR to;
38528 + IPV4_ADDR from;
38529 + LSP_PATH_SHARED_PARAMS lsp_params;
38530 +#if 0 /* Juniper's style */
38531 + FAST_REROUTE *FastReroute;
38532 +#else
38533 + BOOL FastReRoute;
38534 +#endif
38535 + uns32 metric;
38536 + BOOL no_decrement_ttl;
38537 + uns32 bw_policy;
38538 + uns32 retry_timer;
38539 + uns32 retry_limit;
38540 + uns32 retry_count; /* NOT a User's parameter!!! */
38541 + char Primary[16];
38542 + LSP_PATH_SHARED_PARAMS *PrimaryPathParams;
38543 + SECONDARY_PATH_LIST *SecondaryPaths;
38544 + char PolicyName[32];
38545 +} USER_LSP_PARAMS;
38547 +typedef struct
38549 + IPV4_ADDR dest_ip;
38550 + float BW;
38551 + uns16 sla_id;
38552 +} SLA_DATA;
38554 +typedef struct
38556 + void *data;
38557 +} TE_SM_EVENT;
38559 +typedef struct
38561 + uns32 IfIndex;
38562 + uns32 IpAddr;
38563 +} INTERFACE_2_DESTINATION_T;
38565 +typedef struct
38567 + uns32 OutIf; /* Protected I/F */
38568 + PSB_KEY PsbKey; /* for Ingress LSPs */
38569 + unsigned int Label; /* IN label (0 if Ingress, use then PSB_KEY) */
38570 + RR_SUBOBJ *pRro;
38571 +} RRO_CHANGED_HOOK;
38573 +typedef struct
38575 + PSB_KEY key;
38576 + uns32 handle;
38577 + uns32 TeLinkId;
38578 + uns32 OutIf;
38579 + float BW;
38580 + uns8 Priority;
38581 +} BW_HOLD_TIMER_DATA;
38583 +typedef struct
38585 + PSB_KEY key;
38586 +} LSP_SETUP_TIMER_DATA;
38588 +typedef struct
38590 + PSB_KEY key;
38591 +} ADAPTIVITY_TIMER_DATA;
38593 +typedef struct
38595 + PSB_KEY key;
38596 +} LSP_SETUP_RETRY_TIMER_DATA;
38598 +typedef struct
38600 + PSB_KEY key;
38601 +} CSPF_RETRY_TIMER_DATA;
38603 +typedef enum
38605 + BW_HOLD_EXPIRY,
38606 + LSP_SETUP_EXPIRY,
38607 + ADAPTIVITY_EXPIRY,
38608 + LSP_SETUP_RETRY_EXPIRY,
38609 + BYPASS_TUNNEL_RETRY_EXPIRY,
38610 + CSPF_RETRY_EXPIRY,
38611 + MAX_TE_TMR
38612 +} TE_TMR_E;
38614 +typedef struct
38616 + struct thread *thread;
38617 + union
38619 + BW_HOLD_TIMER_DATA bw_hold_data;
38620 + LSP_SETUP_TIMER_DATA lsp_setup_data;
38621 + ADAPTIVITY_TIMER_DATA adaptivity_timer_data;
38622 + LSP_SETUP_RETRY_TIMER_DATA lsp_setup_retry_data;
38623 + FRR_SM_KEY bypass_retry_data;
38624 + CSPF_RETRY_TIMER_DATA cspf_retry_data;
38625 + } data;
38626 + uns32 period;
38627 + uns16 is_active;
38628 + TE_TMR_E type;
38629 +} TE_TMR;
38631 +typedef struct
38633 + IPV4_ADDR Dest;
38634 + uns32 EgressIfId;
38635 +} TRUNK_KEY;
38637 +typedef struct
38639 + unsigned int BypassTunnelsLabel;
38640 + unsigned int MergeNodeLabel;
38641 + uns32 OutIf;
38642 + BOOL MergeNodeLabelValid; /* In case of Merge Node is an Egress, MergeNodeLabel can be 0 */
38643 + FRR_SM_KEY frr_key; /* Who is FRR SM for this label/session */
38644 + PSB_KEY PsbKey; /* for searching the PSB on the LCC */
38645 + IPV4_ADDR MergeNode; /* for updating ERO */
38646 +} BACKUP_FORWARDING_INFORMATION;
38648 +typedef struct _rsvp_lsp_properties_
38650 + float RequestedBW; /* valid during modification */
38651 + uns16 LspId;
38652 +// uns32 card;
38653 + uns32 oIfIndex;
38654 + uns32 Label;
38655 + BOOL tunneled;
38656 + union
38658 + struct
38660 + uns32 HopCount;
38661 + IPV4_ADDR *pErHopsList;
38662 + BACKUP_FORWARDING_INFORMATION BackupForwardingInformation;
38663 + } path;
38664 + PSB_KEY tunnel;
38665 + } forw_info;
38666 + uns8 SetupPriority;
38667 + uns8 HoldPriority;
38668 + uns32 ExcludeAny;
38669 + uns32 IncludeAny;
38670 + uns32 IncludeAll;
38671 + uns8 FrrDesired;
38672 + uns8 LabelRecordingDesired;
38673 + struct _rsvp_lsp_properties_ *next;
38674 +} RSVP_LSP_PROPERTIES;
38676 +typedef struct _rsvp_tunnel_properties_
38678 + uns16 TunnelId;
38679 + uns16 LspId; /* currrently used */
38680 + float AllocatedBW;
38681 + float RequiredBW; /* for LSP modification */
38682 + float ReservableBW; /* for Tunnels & FA */
38683 + void *sm_handle; /* new ingress lsp or modified ingress lsp sm */
38684 + uns32 Cost; /* FA */
38685 + uns32 ColorMask; /* FA */
38686 + BOOL ReRoute; /* During recovery, to prevent multiple recovery */
38687 + BOOL AdjustmentRequired; /* For secondary tunnels only */
38688 + uns16 LastInvokedLspId; /* to pick up new RSVP LSP ID */
38689 + struct _tunnel_id_list_ *pSecondaryTunnels;
38690 + char UserLspName[32];
38691 + char StaticPathName[16];
38692 + TE_TMR lsp_setup_timer;
38693 + TE_TMR adaptivity_timer;
38694 + TE_TMR lsp_setup_retry_timer;
38695 + TE_TMR cspf_retry_timer;
38696 + void *up_sm_handle;
38697 + void *pCrArgs;
38698 + void *pOpenLspParams;
38699 + RSVP_LSP_PROPERTIES *properties;
38700 + struct _rsvp_tunnel_properties_ *next;
38701 + struct _rsvp_tunnel_properties_ *next_user_lsp_tunnel;
38702 +} RSVP_TUNNEL_PROPERTIES;
38705 +typedef struct _user_lsp_
38707 + USER_LSP_PARAMS params;
38708 + char CurrentSecondaryPathName[16];
38709 + uns16 BackupTunnelId;
38710 + //TUNNEL_ID_LIST *TunnelIdList;
38711 + RSVP_TUNNEL_PROPERTIES *pUserLspTunnels;
38712 +} USER_LSP;
38714 +typedef struct _user_lsp_list_
38716 + USER_LSP *lsp;
38717 + struct _user_lsp_list_ *next;
38718 +} USER_LSP_LIST;
38720 +typedef struct
38722 + IPV4_ADDR dest;
38723 + uns16 sla_id;
38724 +} SLA_KEY;
38726 +typedef struct
38728 + PATRICIA_NODE Node;
38729 + SLA_KEY sla_key;
38730 + float BW;
38731 + struct _tunnels_list_ /*TUNNELS_LIST */ *pTunnelsList;
38732 +} SLA_ENTRY;
38734 +typedef struct
38736 + float RequiredBW;
38737 + float ActualBW;
38738 + float UserRequiredBW;
38739 + uns32 sm_handle; /* adaptivity sm */
38740 +} TRUNK_DATA;
38742 +typedef struct
38744 + PATRICIA_NODE Node;
38745 + TRUNK_KEY trunk_key;
38746 + RSVP_TUNNEL_PROPERTIES *Lsps;
38747 + TRUNK_DATA *pTrunkData;
38748 + uns32 TunnelsCounter;
38749 +} TRUNK_ENTRY;
38751 +typedef struct
38753 + PATRICIA_NODE Node;
38754 + unsigned int label;
38755 + uns32 OutIf;
38756 + unsigned int ReceivedOutLabel;
38757 + //V_CARD_ID allocator; /* needed for FRR */
38758 + uns32 IfIndex; /* needed for FRR */
38759 + BACKUP_FORWARDING_INFORMATION BackupForwardingInformation;
38760 +} LABEL_ENTRY;
38762 +typedef struct _bw_owner_data_
38764 + uns32 TeLinkId;
38765 + uns32 OutIf;
38766 + //V_CARD_ID vcard;
38767 + float BW;
38768 + float PreAllocBW;
38769 + TE_TMR BwHoldTimer;
38770 + struct _bw_owner_data_ *next;
38771 +} BW_OWNER_DATA;
38773 +typedef struct
38775 + PATRICIA_NODE Node;
38776 + PSB_KEY key;
38777 + BW_OWNER_DATA *pBwOwnerData;
38778 +} BW_OWNER_ENTRY;
38780 +/**************************************************************************
38781 + * *
38782 + * *
38783 + * ANSI Function Prototypes for internal functions *
38784 + * *
38785 + * *
38786 + * *
38787 + *************************************************************************/
38789 +extern int ExitFlag;
38790 +extern int VcardId;
38792 +#ifdef FATAL_ERROR
38793 +#undef FATAL_ERROR
38794 +#endif
38796 +#define FATAL_ERROR(x) if(x == NULL) \
38798 + LogMsg(ERROR_OUTPUT,"fatal error at %s %d",__FILE__,__LINE__);\
38799 + return -1;\
38801 +extern char if_ip_addr_str[4][16];
38802 +extern char peer_ip_addr_str[5][16];
38803 +extern IPV4_ADDR peer_ip_addr[5];
38804 +extern int lsr_id_ifc;
38806 +typedef struct ip_addr_ll
38808 + char *ip_addr;
38809 + struct ip_addr_ll *next;
38810 +} tIpAddrLl;
38812 +typedef enum
38814 + SEPARATE_NON_ADAPTIVE,
38815 + SEPARATE_ADAPTIVE,
38816 + NON_SEPARATE_SERVICE,
38817 + NON_SEPARATE_SERVICE_BW_ADAPTIVE,
38818 + NON_SEPARATE_TUNNELS,
38819 + ALL_TRUNKS
38820 +} TRUNK_TYPE;
38822 +typedef struct
38824 + EVENTS_E event;
38825 + union
38827 + USER_LSP user_lsp;
38828 + SLA_DATA sla_data;
38829 + BW_HOLD_TIMER_DATA bw_hold_timer_expiry;
38830 + LSP_SETUP_TIMER_DATA lsp_setup_timer_expiry;
38831 + ADAPTIVITY_TIMER_DATA adaptivity_timer_expiry;
38832 + LSP_SETUP_RETRY_TIMER_DATA lsp_setup_retry_timer_expiry;
38833 + TE_SM_EVENT te_sm_event;
38834 + INTERFACE_2_DESTINATION_T interface_2_destination;
38835 +// FRR_SM_KEY bypass_retry_expiry;
38836 + FRR_DATA_SET frr_data_set;
38837 + CSPF_RETRY_TIMER_DATA cspf_retry_data;
38838 + } u;
38839 +} TE_MSG;
38841 +#define DATA_PLANE 1
38842 +#define MPLS_TE_DB 1
38844 +#endif
38846 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/patricia.c quagga-mpls/rsvpd/patricia.c
38847 --- quagga/rsvpd/patricia.c 1969-12-31 18:00:00.000000000 -0600
38848 +++ quagga-mpls/rsvpd/patricia.c 2007-06-14 21:35:58.000000000 -0500
38849 @@ -0,0 +1,578 @@
38850 +#include "general.h"
38851 +#include <zebra.h>
38852 +#include "patricia.h"
38853 +#include "memory.h"
38855 +const static uns8 BitMasks[9] = {
38856 + 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
38859 +static int
38860 +KeyBitMatch (const uns8 * p1, const uns8 * p2, unsigned int bitcount)
38862 + while (bitcount > 8)
38864 + if (*p1 != *p2)
38866 + return (((int) *p1) - ((int) *p2));
38868 + p1++;
38869 + p2++;
38870 + bitcount -= 8;
38873 + return (((int) (*p1 & BitMasks[bitcount])) -
38874 + ((int) (*p2 & BitMasks[bitcount])));
38878 +static PATRICIA_NODE *
38879 +search (const PATRICIA_TREE * const pTree, const uns8 * const key)
38881 + PATRICIA_NODE *pNode;
38882 + PATRICIA_NODE *pPrevNode;
38884 + pNode = (PATRICIA_NODE *) & pTree->root_node;
38886 + do
38888 + pPrevNode = pNode;
38890 + if (m_GET_BIT (key, pNode->bit) == 0)
38892 + pNode = pNode->left;
38894 + else
38896 + pNode = pNode->right;
38900 + while (pNode->bit > pPrevNode->bit);
38902 + return pNode;
38905 +unsigned int
38906 +patricia_tree_init (PATRICIA_TREE * const pTree,
38907 + const PATRICIA_PARAMS * const pParams)
38909 + if (pParams == NULL)
38910 + return E_ERR;
38912 + if ((pParams->key_size < 1) || (pParams->key_size > PATRICIA_MAX_KEY_SIZE))
38913 + return E_ERR;
38915 + pTree->params = *pParams;
38917 + /* Initialize the root node, which is actually part of the tree structure. */
38918 + pTree->root_node.key_info = (uns8 *) 0;
38919 + pTree->root_node.bit = -1;
38920 + pTree->root_node.left = pTree->root_node.right = &pTree->root_node;
38921 + if ((pTree->root_node.key_info =
38922 + (uns8 *) XMALLOC (0, pTree->params.key_size)) == NULL)
38924 + return E_ERR;
38927 + memset (pTree->root_node.key_info, '\0', (uns32) pTree->params.key_size);
38928 + pTree->n_nodes = 0;
38930 + return E_OK;
38934 +unsigned int
38935 +patricia_tree_destroy (PATRICIA_TREE * const pTree)
38937 + patricia_tree_clear (pTree);
38938 + XFREE (0, pTree->root_node.key_info);
38939 + return E_OK;
38943 +void
38944 +patricia_tree_clear (PATRICIA_TREE * const pTree)
38947 + pTree->root_node.left = pTree->root_node.right = &pTree->root_node;
38948 + pTree->n_nodes = 0;
38952 +unsigned int
38953 +patricia_tree_add (PATRICIA_TREE * const pTree, PATRICIA_NODE * const pNode)
38955 + PATRICIA_NODE *pSrch;
38956 + PATRICIA_NODE *pTmpNode;
38957 + PATRICIA_NODE *pPrevNode;
38958 + int bit;
38960 + pTmpNode = search (pTree, pNode->key_info);
38961 + if (m_KEY_CMP (pTree, pNode->key_info, pTmpNode->key_info) == 0)
38963 + return E_ERR; /* duplicate!. */
38966 + bit = 0;
38968 + while (m_GET_BIT (pNode->key_info, bit) ==
38969 + ((pTmpNode->bit < 0) ? 0 : m_GET_BIT (pTmpNode->key_info, bit)))
38971 + bit++;
38974 + pSrch = &pTree->root_node;
38976 + do
38978 + pPrevNode = pSrch;
38979 + if (m_GET_BIT (pNode->key_info, pSrch->bit) == 0)
38980 + pSrch = pSrch->left;
38981 + else
38982 + pSrch = pSrch->right;
38984 + while ((pSrch->bit < bit) && (pSrch->bit > pPrevNode->bit));
38986 + pNode->bit = bit;
38988 + if (m_GET_BIT (pNode->key_info, bit) == 0)
38990 + pNode->left = pNode;
38991 + pNode->right = pSrch;
38993 + else
38995 + pNode->left = pSrch;
38996 + pNode->right = pNode;
38999 + if (m_GET_BIT (pNode->key_info, pPrevNode->bit) == 0)
39001 + pPrevNode->left = pNode;
39003 + else
39005 + pPrevNode->right = pNode;
39008 + pTree->n_nodes++;
39009 + return E_OK;
39013 +unsigned int
39014 +patricia_tree_del (PATRICIA_TREE * const pTree, PATRICIA_NODE * const pNode)
39016 + PATRICIA_NODE *pNextNode;
39017 + PATRICIA_NODE **pLegDownToNode;
39018 + PATRICIA_NODE *pDelNode;
39019 + PATRICIA_NODE **pPrevLeg;
39020 + PATRICIA_NODE **pNextLeg;
39021 + int UpWentRight;
39023 + UpWentRight = 0;
39026 + /* Start left of root (there is no right). */
39027 + pNextNode = &pTree->root_node;
39028 + pLegDownToNode = &pNextNode->left;
39030 + while ((pDelNode = *pLegDownToNode) != pNode)
39032 + if (pDelNode->bit <= pNextNode->bit)
39034 + return E_ERR; /* Key not found. */
39037 + pNextNode = pDelNode;
39038 + pLegDownToNode = ((m_GET_BIT (pNode->key_info, pNextNode->bit) != 0) ?
39039 + &pNextNode->right : &pNextNode->left);
39043 + /* pDelNode points to the one to delete.
39044 + * pLegDownToNode points to the down-pointer which points to it.
39045 + */
39047 + pPrevLeg = pLegDownToNode;
39048 + pNextNode = pNode;
39050 + /* keep going 'down' until we find the one which
39051 + * points back to pNode as an up-pointer.
39052 + */
39054 + while (1)
39056 + UpWentRight = (m_GET_BIT (pNode->key_info, pNextNode->bit) != 0);
39057 + pNextLeg = ((UpWentRight) ? &pNextNode->right : &pNextNode->left);
39058 + pDelNode = *pNextLeg;
39060 + if (pDelNode == pNode)
39061 + break;
39063 + if (pDelNode->bit <= pNextNode->bit)
39065 + return E_ERR; /* panic??? */
39068 + /* loop around again. */
39069 + pNextNode = pDelNode;
39070 + pPrevLeg = pNextLeg;
39073 + /* At this point,
39074 + * pNextNode is the one pointing UP to the one to delete.
39075 + * pPrevLeg points to the down-leg which points to pNextNode
39076 + * UpWentRight is the direction which pNextNode took (in the UP
39077 + * direction) to get to the one to delete.)
39078 + */
39080 + /* We need to rearrange the tree.
39081 + * BE CAREFUL. The order of the following statements
39082 + * is critical.
39083 + */
39084 + pNextNode->bit = pNode->bit; /* it gets the 'bit' value of the evacuee. */
39085 + *pLegDownToNode = pNextNode;
39087 + *pPrevLeg = ((UpWentRight) ? pNextNode->left : pNextNode->right);
39088 + pNextNode->right = pNode->right;
39089 + pNextNode->left = pNode->left;
39091 + pTree->n_nodes--;
39093 + return E_OK;
39097 +PATRICIA_NODE *
39098 +patricia_tree_get (const PATRICIA_TREE * const pTree, const uns8 * const pKey)
39100 + PATRICIA_NODE *pNode;
39102 + /*
39103 + * See if last getNext happened to be same key.
39105 + * Important assumtion: lastNode will be set to NULL if any
39106 + * nodes are deleted from the tree.
39107 + */
39109 + pNode = search (pTree, pKey);
39111 + if ((pNode == &pTree->root_node) ||
39112 + (m_KEY_CMP (pTree, pNode->key_info, pKey) != 0))
39114 + pNode = PATRICIA_NODE_NULL;
39117 + return pNode;
39121 +PATRICIA_NODE *
39122 +patricia_tree_getnext (PATRICIA_TREE * const pTree, const uns8 * const pKey)
39124 + uns8 Target[PATRICIA_MAX_KEY_SIZE];
39125 + PATRICIA_NODE *pSrch;
39126 + PATRICIA_NODE *pPrev;
39127 + register uns8 *p1;
39128 + register uns8 *p2;
39129 + register int bit;
39131 + if (pKey == (const uns8 *) 0)
39133 + /* Start at root of tree. */
39134 + memset (Target, '\0', pTree->params.key_size);
39136 + else
39138 + memcpy (Target, pKey, pTree->params.key_size);
39141 + p1 = Target + pTree->params.key_size - 1; /* point to last byte of key */
39142 + while (p1 >= Target)
39144 + *p1 += 1;
39145 + if (*p1 != '\0')
39147 + break;
39149 + p1--;
39151 + if (p1 < Target)
39153 + return PATRICIA_NODE_NULL;
39156 + pSrch = &pTree->root_node;
39158 + do
39160 + pPrev = pSrch;
39162 + if (m_GET_BIT (Target, pSrch->bit) == 0)
39164 + pSrch = pSrch->left;
39166 + else
39168 + pSrch = pSrch->right;
39171 + if (pSrch->bit <= pPrev->bit)
39173 + if ((memcmp (Target, pSrch->key_info, pTree->params.key_size) <= 0)
39174 + && (KeyBitMatch (Target, pSrch->key_info, 1 + pPrev->bit) == 0))
39176 + return pSrch;
39179 + do
39181 + if (pSrch == pPrev->left)
39183 + /* We went left to get here */
39184 + if (pPrev->bit < 0)
39186 + return PATRICIA_NODE_NULL;
39188 + pSrch = pPrev;
39190 + p1 = pSrch->key_info;
39191 + p2 = Target;
39193 + for (bit = pSrch->bit; bit >= 8; bit -= 8)
39195 + *p2++ = *p1++;
39197 + /* Bring over SOME of the bits from pSrch. */
39198 + *p2 = (uns8) (*p1 & ((uns8) (BitMasks[bit])));
39200 + *p2 |= (uns8) (0x80 >> bit);
39202 + p2++;
39204 + while (p2 < (Target + pTree->params.key_size))
39206 + *p2++ = '\0';
39208 + break;
39210 + else
39212 + /* We went right to get here */
39213 + if (pPrev->bit <= 0)
39215 + return PATRICIA_NODE_NULL;
39218 + p1 = pPrev->key_info;
39219 + p2 = Target;
39221 + for (bit = pPrev->bit; bit >= 8; bit -= 8)
39223 + *p2++ = *p1++;
39225 + if (bit > 0)
39227 + *p2 = (uns8) (*p1 & BitMasks[bit]);
39229 + *p2 |= (uns8) (0xff >> bit);
39230 + for (p1 = p2 + 1; p1 < (Target + pTree->params.key_size);
39231 + p1++)
39233 + *p1 = '\0';
39235 + do
39237 + ++*p2;
39238 + if (*p2 != '\0')
39240 + break;
39243 + while (--p2 >= Target);
39245 + if (p2 < Target)
39247 + return PATRICIA_NODE_NULL;
39250 + pSrch = pPrev;
39252 + pPrev = &pTree->root_node;
39253 + do
39255 + if (m_GET_BIT (pSrch->key_info, pPrev->bit) == 0)
39257 + if (pPrev->left == pSrch)
39259 + break;
39261 + pPrev = pPrev->left;
39263 + else
39265 + if (pPrev->right == pSrch)
39267 + break;
39269 + pPrev = pPrev->right;
39273 + while (TRUE);
39275 + if (KeyBitMatch (Target, pSrch->key_info, 1 + pSrch->bit) ==
39276 + 0)
39278 + break;
39283 + while (TRUE);
39285 + } /* if (pSrch->bit <= pPrev->bit) */
39286 + else
39288 + /* We're still going 'down'... but make sure we haven't gone down too far. */
39289 + bit = KeyBitMatch (Target, pSrch->key_info, pSrch->bit);
39291 + if (bit < 0)
39293 + p1 = pSrch->key_info;
39294 + p2 = Target;
39295 + for (bit = pSrch->bit; bit >= 8; bit -= 8)
39297 + *p2++ = *p1++;
39299 + if (bit != 0)
39301 + *p2++ = ((uns8) (*p1 & BitMasks[bit]));
39303 + while (p2 < Target + pTree->params.key_size)
39305 + *p2++ = '\0';
39308 + else if (bit > 0)
39311 + do
39313 + if (pSrch == pPrev->left)
39315 + /* We went left to get here */
39316 + if (pPrev->bit < 0)
39318 + return PATRICIA_NODE_NULL;
39320 + pSrch = pPrev;
39322 + p1 = pSrch->key_info;
39323 + p2 = Target;
39325 + for (bit = pSrch->bit; bit >= 8; bit -= 8)
39327 + *p2++ = *p1++;
39329 + /* Bring over SOME of the bits from pSrch. */
39330 + *p2 = (uns8) (*p1 & ((uns8) (BitMasks[bit])));
39332 + *p2 |= (uns8) (0x80 >> bit);
39334 + p2++;
39336 + while (p2 < (Target + pTree->params.key_size))
39338 + *p2++ = '\0';
39340 + break;
39342 + else
39344 + /* We went right to get here */
39345 + if (pPrev->bit <= 0)
39347 + return PATRICIA_NODE_NULL;
39350 + p1 = pPrev->key_info;
39351 + p2 = Target;
39353 + for (bit = pPrev->bit; bit >= 8; bit -= 8)
39355 + *p2++ = *p1++;
39357 + if (bit > 0)
39359 + *p2 = (uns8) (*p1 & BitMasks[bit]);
39361 + *p2 |= (uns8) (0xff >> bit);
39362 + for (p1 = p2 + 1;
39363 + p1 < (Target + pTree->params.key_size); p1++)
39365 + *p1 = '\0';
39367 + do
39369 + ++*p2;
39370 + if (*p2 != '\0')
39372 + break;
39375 + while (--p2 >= Target);
39377 + if (p2 < Target)
39379 + return PATRICIA_NODE_NULL;
39382 + pSrch = pPrev;
39384 + pPrev = &pTree->root_node;
39385 + do
39387 + if (m_GET_BIT (pSrch->key_info, pPrev->bit) == 0)
39389 + if (pPrev->left == pSrch)
39391 + break;
39393 + pPrev = pPrev->left;
39395 + else
39397 + if (pPrev->right == pSrch)
39399 + break;
39401 + pPrev = pPrev->right;
39405 + while (TRUE);
39407 + if (KeyBitMatch
39408 + (Target, pSrch->key_info, 1 + pSrch->bit) == 0)
39410 + break;
39415 + while (TRUE);
39419 + while (TRUE);
39423 +int
39424 +patricia_tree_size (const PATRICIA_TREE * const pTree)
39426 + return pTree->n_nodes;
39428 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/patricia.h quagga-mpls/rsvpd/patricia.h
39429 --- quagga/rsvpd/patricia.h 1969-12-31 18:00:00.000000000 -0600
39430 +++ quagga-mpls/rsvpd/patricia.h 2007-06-14 21:35:58.000000000 -0500
39431 @@ -0,0 +1,56 @@
39433 +#ifndef _PATRICIA_H_
39434 +#define _PATRICIA_H_
39436 +#include "general.h"
39438 +typedef struct patricia_params
39440 + int key_size; /* 1..PATRICIA_MAX_KEY_SIZE - in OCTETS */
39441 + int info_size; /* NOT USED! Present for backward-compatibility only! */
39442 + int actual_key_size; /* NOT USED! Present for backward-compatibility only! */
39443 + int node_size; /* NOT USED! Present for backward compatibitity only! */
39444 +} PATRICIA_PARAMS;
39446 +#define PATRICIA_MAX_KEY_SIZE 256 /* # octets */
39449 +typedef struct patricia_node
39451 + int bit; /* must be signed type (bits start at -1) */
39452 + struct patricia_node *left;
39453 + struct patricia_node *right;
39454 + uns8 *key_info;
39455 +} PATRICIA_NODE;
39457 +#define PATRICIA_NODE_NULL ((PATRICIA_NODE *)0)
39459 +typedef uns8 PATRICIA_LEXICAL_STACK; /* ancient history... */
39461 +typedef struct patricia_tree
39463 + PATRICIA_NODE root_node; /* A tree always has a root node. */
39464 + PATRICIA_PARAMS params;
39465 + unsigned int n_nodes;
39466 +} PATRICIA_TREE;
39469 +#define m_KEY_CMP(t, k1, k2) memcmp(k1, k2, (size_t)(t)->params.key_size)
39470 +#define m_GET_BIT(key, bit) ((bit < 0) ? 0 : ((int)((*((key) + (bit >> 3))) >> (7 - (bit & 0x07))) & 0x01))
39472 +unsigned int patricia_tree_init (PATRICIA_TREE * const pTree,
39473 + const PATRICIA_PARAMS * const pParams);
39474 +unsigned int patricia_tree_destroy (PATRICIA_TREE * const pTree);
39475 +void patricia_tree_clear (PATRICIA_TREE * const pTree);
39476 +unsigned int patricia_tree_add (PATRICIA_TREE * const pTree,
39477 + PATRICIA_NODE * const pNode);
39478 +unsigned int patricia_tree_del (PATRICIA_TREE * const pTree,
39479 + PATRICIA_NODE * const pNode);
39480 +PATRICIA_NODE *patricia_tree_get (const PATRICIA_TREE * const pTree,
39481 + const uns8 * const pKey);
39482 +PATRICIA_NODE *patricia_tree_get_best (const PATRICIA_TREE * const pTree, const uns8 * const pKey, uns16 KeyLen); /* Length of key (in BITS) */
39483 +PATRICIA_NODE *patricia_tree_getnext (PATRICIA_TREE * const pTree, const uns8 * const pKey); /* NULL means get 1st */
39485 +int patricia_tree_size (const PATRICIA_TREE * const pTree);
39487 +#endif
39488 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_api.c quagga-mpls/rsvpd/rsvp_api.c
39489 --- quagga/rsvpd/rsvp_api.c 1969-12-31 18:00:00.000000000 -0600
39490 +++ quagga-mpls/rsvpd/rsvp_api.c 2007-07-03 00:30:00.000000000 -0500
39491 @@ -0,0 +1,239 @@
39492 +/* Module: rsvp_api.c
39493 + Contains: RSVP in-process API functions
39494 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
39495 + */
39497 +#include "rsvp.h"
39499 +void
39500 +RsvpPathSendCmd (TE_API_MSG * pMsg)
39502 + if (IngressPathSend (&pMsg->u.IngressApi) != E_OK)
39504 + zlog_err ("Cannot invoke PATH");
39508 +void
39509 +RsvpPathTearCmd (TE_API_MSG * pMsg)
39511 + if (IngressPathTear (&pMsg->u.IngressApi) != E_OK)
39513 + zlog_err ("Cannot invoke PATH_TEAR");
39516 +extern uns32 PathRefreshInterval;
39517 +E_RC
39518 +IngressPathSend (INGRESS_API * pIngressApi)
39520 + PSB_KEY PsbKey;
39521 + PSB *pPsb;
39522 + RSVP_PKT *pRsvpPkt;
39523 + memset (&PsbKey, 0, sizeof (PSB_KEY));
39524 + PsbKey.Session.Dest = pIngressApi->Egress;
39525 + PsbKey.Session.TunnelId = pIngressApi->TunnelId;
39526 + PsbKey.Session.ExtTunelId = pIngressApi->src_ip;
39527 + PsbKey.SenderTemplate.IpAddr = PsbKey.Session.ExtTunelId;
39528 + PsbKey.SenderTemplate.LspId = pIngressApi->LspId;
39529 + if ((pPsb = FindPsb (&PsbKey)) != NULL)
39531 + zlog_err ("RSVP LSP exists in this tunnel");
39532 + return E_ERR;
39534 + if ((pPsb = NewPsb (&PsbKey)) == NULL)
39536 + zlog_err ("Cannot create PSB");
39538 + pRsvpPkt = &pPsb->OldPacket;
39539 + pRsvpPkt->Session = PsbKey.Session;
39540 + pRsvpPkt->SenderTemplate = PsbKey.SenderTemplate;
39541 + pRsvpPkt->SentRsvpHop.LIH = pIngressApi->OutIfIndex;
39542 + pPsb->NextHop = pIngressApi->NextHop;
39543 + pPsb->OutIfIndex = pIngressApi->OutIfIndex;
39544 + pPsb->RefreshValue = PathRefreshInterval;
39545 + pPsb->ttl = 255;
39546 + if (IpAddrGetByIfIndex (pPsb->OutIfIndex, &pRsvpPkt->SentRsvpHop.PHop) !=
39547 + E_OK)
39549 + zlog_err ("Cannot get IP address by IfIndex %x", pPsb->OutIfIndex);
39550 + return E_ERR;
39552 + else
39554 + pPsb->OldPacket.SentRsvpHop.PHop = pPsb->OldPacket.SentRsvpHop.PHop;
39555 + zlog_info ("NHOP %x", pPsb->NextHop);
39557 + pRsvpPkt->LabelRequest.L3Pid = 0x800;
39558 + pRsvpPkt->TimeValues.TimeValues = PathRefreshInterval * 1000;
39559 + pRsvpPkt->SenderTSpec.MessageHdr.VersionResvd = 0;
39560 + pRsvpPkt->SenderTSpec.MessageHdr.MessageLength = 7;
39561 + pRsvpPkt->SenderTSpec.ServHdr.ServHdr = 1;
39562 + pRsvpPkt->SenderTSpec.ServHdr.ServLength = 6;
39563 + pRsvpPkt->SenderTSpec.ParamHdr.ParamID = 127;
39564 + pRsvpPkt->SenderTSpec.ParamHdr.ParamLength = 5;
39565 + pRsvpPkt->SenderTSpec.MaxPacketSize = 1500;
39566 + pRsvpPkt->SenderTSpec.PeakDataRate = pIngressApi->BW;
39567 + pRsvpPkt->SenderTSpec.MinPolicedUnit = 40;
39568 + pRsvpPkt->SenderTSpec.TockenBucketRate = pIngressApi->BW;
39569 + pRsvpPkt->SenderTSpec.TockenBucketSize = 1;
39570 + if (pIngressApi->HopNum > 0)
39572 + zlog_info ("calling InsertERO %d", pIngressApi->HopNum);
39573 + if (InsertERO
39574 + (&pRsvpPkt->SentEro, pIngressApi->Path,
39575 + pIngressApi->HopNum) != E_OK)
39577 + FreeERO (&pRsvpPkt->SentEro);
39578 + zlog_err ("Cannot allocate ERO");
39579 + return E_ERR;
39583 + if (pIngressApi->LabelRecordingDesired)
39585 + if (InsertRRO (pRsvpPkt) != E_OK)
39587 + FreeRRO (&pRsvpPkt->AddedRro);
39588 + zlog_err ("Cannot allocate RRO");
39589 + return E_ERR;
39593 + if (pIngressApi->RaValid)
39595 + pRsvpPkt->SessionAttributes.CType = SESSION_ATTRIBUTES_RA_IPV4_CTYPE;
39596 + pRsvpPkt->SessionAttributes.u.SessAttrRa.ExcludeAny =
39597 + pIngressApi->ExcludeAny;
39598 + pRsvpPkt->SessionAttributes.u.SessAttrRa.IncludeAll =
39599 + pIngressApi->IncludeAll;
39600 + pRsvpPkt->SessionAttributes.u.SessAttrRa.IncludeAny =
39601 + pIngressApi->IncludeAny;
39602 + pRsvpPkt->SessionAttributes.u.SessAttrRa.SetPrio = pIngressApi->SetPrio;
39603 + pRsvpPkt->SessionAttributes.u.SessAttrRa.HoldPrio =
39604 + pIngressApi->HoldPrio;
39605 + if (pIngressApi->Shared)
39606 + pRsvpPkt->SessionAttributes.u.SessAttrRa.Flags |= SE_STYLE_DESIRED;
39607 + if (pIngressApi->FrrDesired)
39608 + pRsvpPkt->SessionAttributes.u.SessAttrRa.Flags |=
39609 + LOCAL_PROTECTION_DESIRED;
39610 + if (pIngressApi->LabelRecordingDesired)
39611 + pRsvpPkt->SessionAttributes.u.SessAttrRa.Flags |=
39612 + LABEL_RECORDING_DESIRED;
39613 + if ((pRsvpPkt->SessionAttributes.u.SessAttrRa.SessionName =
39614 + (char *) XMALLOC (MTYPE_RSVP, strlen ("VADIM SURAEV "))) != NULL)
39616 + strcpy (pRsvpPkt->SessionAttributes.u.SessAttrRa.SessionName,
39617 + "VADIM SURAEV ");
39618 + pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength =
39619 + strlen ("VADIM SURAEV ");
39622 + else
39624 + pRsvpPkt->SessionAttributes.CType = SESSION_ATTRIBUTES_IPV4_CTYPE;
39625 + pRsvpPkt->SessionAttributes.u.SessAttr.SetPrio = pIngressApi->SetPrio;
39626 + pRsvpPkt->SessionAttributes.u.SessAttr.HoldPrio = pIngressApi->HoldPrio;
39628 + if (pIngressApi->Shared)
39629 + pRsvpPkt->SessionAttributes.u.SessAttr.Flags |= SE_STYLE_DESIRED;
39630 + if (pIngressApi->FrrDesired)
39631 + pRsvpPkt->SessionAttributes.u.SessAttr.Flags |=
39632 + LOCAL_PROTECTION_DESIRED;
39633 + if (pIngressApi->LabelRecordingDesired)
39634 + pRsvpPkt->SessionAttributes.u.SessAttr.Flags |=
39635 + LABEL_RECORDING_DESIRED;
39636 + if ((pRsvpPkt->SessionAttributes.u.SessAttr.SessionName =
39637 + (char *) XMALLOC (MTYPE_RSVP,
39638 + strlen ("VADIM SURAEV ") + 1)) != NULL)
39640 + strcpy (pRsvpPkt->SessionAttributes.u.SessAttr.SessionName,
39641 + "VADIM SURAEV ");
39642 + pRsvpPkt->SessionAttributes.u.SessAttr.NameLength =
39643 + strlen ("VADIM SURAEV ");
39647 + return RsvpPathRefresh (pPsb);
39650 +E_RC
39651 +IngressPathTear (INGRESS_API * pIngressApi)
39653 + PSB_KEY PsbKey;
39654 + PSB *pPsb;
39656 + memset (&PsbKey, 0, sizeof (PSB_KEY));
39657 + PsbKey.Session.Dest = pIngressApi->Egress;
39658 + PsbKey.Session.TunnelId = pIngressApi->TunnelId;
39659 + PsbKey.Session.ExtTunelId = pIngressApi->src_ip;
39660 + PsbKey.SenderTemplate.IpAddr = PsbKey.Session.ExtTunelId;
39661 + PsbKey.SenderTemplate.LspId = pIngressApi->LspId;
39662 + if ((pPsb = FindPsb (&PsbKey)) == NULL)
39664 + zlog_err ("RSVP LSP %x does not exist in this tunnel %x %x %x",
39665 + pIngressApi->LspId, pIngressApi->Egress,
39666 + pIngressApi->TunnelId, pIngressApi->src_ip);
39667 + return E_ERR;
39669 + if (EncodeAndSendRsvpPathTearMessage
39670 + (&pPsb->OldPacket, pPsb->NextHop, pPsb->OutIfIndex,
39671 + pPsb->ttl - 1) != E_OK)
39673 + zlog_err ("Cannot encode/send RSVP PathTear %s %d", __FILE__, __LINE__);
39675 + if (DeleteSender (pPsb) != E_OK)
39677 + zlog_err ("An error on DeleteSender %s %d", __FILE__, __LINE__);
39679 + return E_OK;
39682 +E_RC
39683 +DebugSendResvTear (TE_API_MSG * pMsg)
39685 + DEBUG_SEND_RESV_TEAR *pDbgResvTear = &pMsg->u.DebugSendResvTear;
39686 + RSB *pRsb;
39687 + RSB_KEY RsbKey;
39688 + RSVP_PKT *pRsvpPkt;
39689 + int i;
39691 + RsbKey = pDbgResvTear->RsbKey;
39692 + if ((pRsb = FindRsb (&RsbKey)) == NULL)
39694 + zlog_err ("Cannot find RSB %x %x %x %s %d",
39695 + RsbKey.Session.Dest,
39696 + RsbKey.Session.TunnelId,
39697 + RsbKey.Session.ExtTunelId, __FILE__, __LINE__);
39698 + return E_ERR;
39700 + if ((pRsvpPkt =
39701 + (RSVP_PKT *) XMALLOC (MTYPE_RSVP, sizeof (RSVP_PKT))) == NULL)
39703 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
39704 + return E_ERR;
39706 + memset (pRsvpPkt, 0, sizeof (RSVP_PKT));
39707 + pRsvpPkt->Session = RsbKey.Session;
39708 + pRsvpPkt->Style = pRsb->OldPacket.Style;
39709 + for (i = 0; i < pDbgResvTear->FilterSpecNumber; i++)
39711 + FILTER_SPEC_DATA *pFilterSpecData;
39712 + if ((pFilterSpecData =
39713 + (FILTER_SPEC_DATA *) XMALLOC (MTYPE_RSVP,
39714 + sizeof (FILTER_SPEC_DATA))) == NULL)
39716 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
39717 + FreeRsvpPkt (pRsvpPkt);
39718 + return E_ERR;
39720 + memset (pFilterSpecData, 0, sizeof (FILTER_SPEC_DATA));
39721 + pFilterSpecData->FilterSpec = pDbgResvTear->FilterSpecs[i];
39722 + if (NewFilterListNode (&pRsvpPkt->pFilterList, pFilterSpecData) != E_OK)
39724 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
39725 + FreeRsvpPkt (pRsvpPkt);
39726 + return E_ERR;
39729 + return ProcessRsvpResvTearMessage (pRsvpPkt);
39731 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_api.h quagga-mpls/rsvpd/rsvp_api.h
39732 --- quagga/rsvpd/rsvp_api.h 1969-12-31 18:00:00.000000000 -0600
39733 +++ quagga-mpls/rsvpd/rsvp_api.h 2007-07-03 00:39:59.000000000 -0500
39734 @@ -0,0 +1,9 @@
39735 +#ifndef _RSVP_API_H_
39736 +#define _RSVP_API_H_
39738 +E_RC IngressPathSend (INGRESS_API * pIngressApi);
39739 +E_RC IngressPathTear (INGRESS_API * pIngressApi);
39740 +E_RC DebugSendResvTear (TE_API_MSG * pMsg);
39741 +void RsvpPathSendCmd (TE_API_MSG * pMsg);
39742 +void RsvpPathTearCmd (TE_API_MSG * pMsg);
39743 +#endif
39744 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvpd.conf.sample quagga-mpls/rsvpd/rsvpd.conf.sample
39745 --- quagga/rsvpd/rsvpd.conf.sample 1969-12-31 18:00:00.000000000 -0600
39746 +++ quagga-mpls/rsvpd/rsvpd.conf.sample 2007-07-02 22:59:34.000000000 -0500
39747 @@ -0,0 +1,16 @@
39749 +! Zebra configuration saved from vty
39750 +! 2004/05/31 00:43:53
39752 +hostname mpls_te
39753 +password zebra
39755 +line vty
39757 +interface tunnel Cisco1
39758 + tunnel destination 10.13.163.170
39759 + tunnel mpls traffic-eng bandwidth 1000
39760 + exit
39761 +interface tunnel Cisco0
39762 + tunnel destination 10.13.163.170
39763 + exit
39764 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_decode.c quagga-mpls/rsvpd/rsvp_decode.c
39765 --- quagga/rsvpd/rsvp_decode.c 1969-12-31 18:00:00.000000000 -0600
39766 +++ quagga-mpls/rsvpd/rsvp_decode.c 2007-07-02 22:50:59.000000000 -0500
39767 @@ -0,0 +1,1005 @@
39768 +/* Module: rsvp_decode.c
39769 + Contains: RSVP packet decoding functions which parse
39770 + the received packet.
39771 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
39772 + */
39773 +#include "rsvp.h"
39775 +uns32
39776 +decode_24bit (uns8 ** stream)
39779 + uns32 val = 0; /* Accumulator */
39782 + val = (uns32) * (*stream)++ << 16;
39783 + val |= (uns32) * (*stream)++ << 8;
39784 + val |= (uns32) * (*stream)++;
39786 + return (val & 0x00FFFFFF);
39790 +uns32
39791 +decode_32bit (uns8 ** stream)
39794 + uns32 val = 0; /* Accumulator */
39797 + val = (uns32) * (*stream)++ << 24;
39798 + val |= (uns32) * (*stream)++ << 16;
39799 + val |= (uns32) * (*stream)++ << 8;
39800 + val |= (uns32) * (*stream)++;
39802 + return val;
39805 +uns16
39806 +decode_16bit (uns8 ** stream)
39809 + uns32 val = 0; /* Accumulator */
39812 + val = (uns32) * (*stream)++ << 8;
39813 + val |= (uns32) * (*stream)++;
39815 + return (uns16) (val & 0x0000FFFF);
39818 +uns8
39819 +decode_8bit (uns8 ** stream)
39822 + uns32 val = 0; /* Accumulator */
39824 + val = (uns32) * (*stream)++;
39826 + return (uns8) (val & 0x000000FF);
39829 +#define DECODE_FLOAT(n, dec) {\
39830 + *((uns32 *) (dec)) = (n); \
39833 +float
39834 +decode_float (uns8 ** stream)
39836 + uns32 val;
39837 + float ret_val;
39839 + val = (uns32) * (*stream)++ << 24;
39840 + val |= (uns32) * (*stream)++ << 16;
39841 + val |= (uns32) * (*stream)++ << 8;
39842 + val |= (uns32) * (*stream)++;
39843 + DECODE_FLOAT (val, &ret_val) return ret_val;
39846 +#define DECODE_COMMON_HDR \
39848 + RsvpCommonHdr.VersionFlags = decode_8bit((uns8 **)&pData);\
39849 + RsvpCommonHdr.MsgType = decode_8bit((uns8 **)&pData);\
39850 + RsvpCommonHdr.CheckSum = decode_16bit((uns8 **)&pData);\
39851 + RsvpCommonHdr.SendTTL = decode_8bit((uns8 **)&pData);\
39852 + RsvpCommonHdr.Resvd = decode_8bit((uns8 **)&pData);\
39853 + RsvpCommonHdr.RsvpLength = decode_16bit((uns8 **)&pData);\
39856 +#define DECODE_OBJ_HDR \
39858 + pObjHdr = *ppData;\
39859 + pObjHdr->Length = decode_16bit((uns8 **)ppData);\
39860 + pObjHdr->ClassNum = decode_8bit((uns8 **)ppData);\
39861 + pObjHdr->CType = decode_8bit((uns8 **)ppData);\
39864 +typedef struct
39866 + E_RC (*pObjDecoder) (void **, RSVP_PKT * pRsvpPkt, OBJ_HDR * pObjHdr,
39867 + uns32 RemainingLen);
39868 +} DECODE_HANDLER;
39870 +#define MAX_OBJS 300
39872 +DECODE_HANDLER DecodeHandlers[MAX_OBJS];
39874 +E_RC
39875 +SessionDecoder (void **ppData, RSVP_PKT * pRsvpPkt, OBJ_HDR * pObjHdr,
39876 + uns32 RemainingLen)
39878 + pRsvpPkt->Session.Dest = decode_32bit ((uns8 **) ppData);
39879 + pRsvpPkt->Session.Resvd = decode_16bit ((uns8 **) ppData);
39880 + pRsvpPkt->Session.TunnelId = decode_16bit ((uns8 **) ppData);
39881 + pRsvpPkt->Session.ExtTunelId = decode_32bit ((uns8 **) ppData);
39882 + zlog_info ("Dest %x TunnelId %x ExtTunnelId %x",
39883 + pRsvpPkt->Session.Dest,
39884 + pRsvpPkt->Session.TunnelId, pRsvpPkt->Session.ExtTunelId);
39885 + return E_OK;
39888 +E_RC
39889 +RsvpHopDecoder (void **ppData, RSVP_PKT * pRsvpPkt, OBJ_HDR * pObjHdr,
39890 + uns32 RemainingLen)
39892 + pRsvpPkt->ReceivedRsvpHop.PHop = decode_32bit ((uns8 **) ppData);
39893 + pRsvpPkt->ReceivedRsvpHop.LIH = decode_32bit ((uns8 **) ppData);
39894 + zlog_info ("RSVP HOP %x %x", pRsvpPkt->ReceivedRsvpHop.PHop,
39895 + pRsvpPkt->ReceivedRsvpHop.LIH);
39896 + return E_OK;
39899 +E_RC
39900 +TimeValuesDecoder (void **ppData, RSVP_PKT * pRsvpPkt, OBJ_HDR * pObjHdr,
39901 + uns32 RemainingLen)
39903 + pRsvpPkt->TimeValues.TimeValues = decode_32bit ((uns8 **) ppData);
39904 + zlog_info ("Time Values %x", pRsvpPkt->TimeValues.TimeValues);
39905 + return E_OK;
39908 +E_RC
39909 +SenderTemplateDecoder (void **ppData, RSVP_PKT * pRsvpPkt, OBJ_HDR * pObjHdr,
39910 + uns32 RemainingLen)
39912 + pRsvpPkt->SenderTemplate.IpAddr = decode_32bit ((uns8 **) ppData);
39913 + pRsvpPkt->SenderTemplate.Resvd = decode_16bit ((uns8 **) ppData);
39914 + pRsvpPkt->SenderTemplate.LspId = decode_16bit ((uns8 **) ppData);
39915 + zlog_info ("IP %x LSP ID %x", pRsvpPkt->SenderTemplate.IpAddr,
39916 + pRsvpPkt->SenderTemplate.LspId);
39917 + return E_OK;
39920 +E_RC
39921 +LabelReqDecoder (void **ppData, RSVP_PKT * pRsvpPkt, OBJ_HDR * pObjHdr,
39922 + uns32 RemainingLen)
39924 + pRsvpPkt->LabelRequest.Resvd = decode_16bit ((uns8 **) ppData);
39925 + pRsvpPkt->LabelRequest.L3Pid = decode_16bit ((uns8 **) ppData);
39926 + zlog_info ("Label Request");
39927 + return E_OK;
39930 +E_RC
39931 +ERO_Decoder (void **ppData, RSVP_PKT * pRsvpPkt, OBJ_HDR * pObjHdr,
39932 + uns32 RemainingLen)
39934 + int Count;
39935 + ER_SUBOBJ *pErSubObj, *pPrev = NULL;
39936 + int Len = pObjHdr->Length - sizeof (OBJ_HDR);
39937 + zlog_info ("entering ERO_Decoder");
39938 + if (Len % 8)
39940 + zlog_err (" the length is not 8-alligned");
39942 + Count = Len / 8;
39943 + while (Len > 0)
39945 + if ((pErSubObj =
39946 + (ER_SUBOBJ *) XMALLOC (MTYPE_RSVP, sizeof (ER_SUBOBJ))) == NULL)
39948 + zlog_err (" malloc failed ");
39949 + return E_ERR;
39951 + memset (pErSubObj, 0, sizeof (ER_SUBOBJ));
39952 + if (pRsvpPkt->ReceivedEro.er == NULL)
39954 + pRsvpPkt->ReceivedEro.er = pErSubObj;
39956 + else
39958 + pPrev->next = pErSubObj;
39960 + pErSubObj->SubObjHdr.LType = decode_8bit ((uns8 **) ppData);
39961 + pErSubObj->SubObjHdr.Length = decode_8bit ((uns8 **) ppData);
39962 + Len -= 8;
39963 + if (pErSubObj->SubObjHdr.Length != 8)
39965 + zlog_err (" the length of subobject is not 8!!!");
39966 + return E_ERR;
39968 + switch (pErSubObj->SubObjHdr.LType & 0x7F)
39970 + case ERO_SUBTYPE_IPV4:
39971 + pErSubObj->u.Ipv4.IpAddress = decode_32bit ((uns8 **) ppData);
39972 + pErSubObj->u.Ipv4.PrefixLength = decode_8bit ((uns8 **) ppData);
39973 + pErSubObj->u.Ipv4.Resvd = decode_8bit ((uns8 **) ppData);
39974 + zlog_info ("ERO subobject: IP %x prefix length %x",
39975 + pErSubObj->u.Ipv4.IpAddress,
39976 + pErSubObj->u.Ipv4.PrefixLength);
39977 + break;
39978 + default:
39979 + zlog_err ("the type %d of subobject is unknown %s %d",
39980 + (pErSubObj->SubObjHdr.LType & 0x7F), __FILE__, __LINE__);
39981 + return E_ERR;
39983 + pPrev = pErSubObj;
39985 + zlog_info ("leaving ERO_Decoder");
39986 + return E_OK;
39989 +E_RC
39990 +SessionAttrDecoder (void **ppData, RSVP_PKT * pRsvpPkt, OBJ_HDR * pObjHdr,
39991 + uns32 RemainingLen)
39993 + char *pP;
39995 + pRsvpPkt->SessionAttributes.CType = pObjHdr->CType;
39996 + if (pObjHdr->CType == SESSION_ATTRIBUTES_CLASS_TYPE)
39998 + pRsvpPkt->SessionAttributes.u.SessAttr.SetPrio =
39999 + decode_8bit ((uns8 **) ppData);
40000 + pRsvpPkt->SessionAttributes.u.SessAttr.HoldPrio =
40001 + decode_8bit ((uns8 **) ppData);
40002 + pRsvpPkt->SessionAttributes.u.SessAttr.Flags =
40003 + decode_8bit ((uns8 **) ppData);
40004 + pRsvpPkt->SessionAttributes.u.SessAttr.NameLength =
40005 + decode_8bit ((uns8 **) ppData);
40006 + if ((pRsvpPkt->SessionAttributes.u.SessAttr.NameLength % 4)
40007 + && (pRsvpPkt->SessionAttributes.u.SessAttr.NameLength))
40009 + zlog_err ("Session name length is %d must be multiple of 4",
40010 + pRsvpPkt->SessionAttributes.u.SessAttr.NameLength);
40011 + return E_ERR;
40013 + if (pRsvpPkt->SessionAttributes.u.SessAttr.NameLength < 8)
40015 + zlog_err ("Session name length is %d must be at least 8",
40016 + pRsvpPkt->SessionAttributes.u.SessAttr.NameLength);
40017 + //return E_ERR; currently, ignore
40019 + if (pRsvpPkt->SessionAttributes.u.SessAttr.NameLength != 0)
40021 + pP = *ppData;
40022 + if ((pRsvpPkt->SessionAttributes.u.SessAttr.SessionName =
40023 + (char *) XMALLOC (MTYPE_RSVP,
40024 + sizeof (char) *
40025 + pRsvpPkt->SessionAttributes.u.SessAttr.
40026 + NameLength)) == NULL)
40028 + zlog_err ("cannot allocate memory %s %d", __FILE__, __LINE__);
40029 + return E_ERR;
40031 + memset (pRsvpPkt->SessionAttributes.u.SessAttr.SessionName, 0,
40032 + sizeof (char) *
40033 + pRsvpPkt->SessionAttributes.u.SessAttr.NameLength);
40034 + strncpy (pRsvpPkt->SessionAttributes.u.SessAttr.SessionName, pP,
40035 + pRsvpPkt->SessionAttributes.u.SessAttr.NameLength);
40036 + pP += pRsvpPkt->SessionAttributes.u.SessAttr.NameLength;
40037 + *ppData = pP;
40040 + else if (pObjHdr->CType == SESSION_ATTRIBUTES_RA_CLASS_TYPE)
40042 + pRsvpPkt->SessionAttributes.u.SessAttrRa.ExcludeAny =
40043 + decode_32bit ((uns8 **) ppData);
40044 + pRsvpPkt->SessionAttributes.u.SessAttrRa.IncludeAny =
40045 + decode_32bit ((uns8 **) ppData);
40046 + pRsvpPkt->SessionAttributes.u.SessAttrRa.IncludeAll =
40047 + decode_32bit ((uns8 **) ppData);
40048 + pRsvpPkt->SessionAttributes.u.SessAttrRa.SetPrio =
40049 + decode_8bit ((uns8 **) ppData);
40050 + pRsvpPkt->SessionAttributes.u.SessAttrRa.HoldPrio =
40051 + decode_8bit ((uns8 **) ppData);
40052 + pRsvpPkt->SessionAttributes.u.SessAttrRa.Flags =
40053 + decode_8bit ((uns8 **) ppData);
40054 + pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength =
40055 + decode_8bit ((uns8 **) ppData);
40056 + if (pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength % 4)
40058 + zlog_err ("Session name length is %d must be multiple of 4",
40059 + pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength);
40060 + return E_ERR;
40062 + if (pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength < 8)
40064 + zlog_err ("Session name length is %d must be at least 8",
40065 + pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength);
40066 + //return E_ERR;currently, ingnore
40068 + if (pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength != 0)
40070 + pP = *ppData;
40071 + if ((pRsvpPkt->SessionAttributes.u.SessAttrRa.SessionName =
40072 + (char *) XMALLOC (MTYPE_RSVP,
40073 + sizeof (char) *
40074 + pRsvpPkt->SessionAttributes.u.SessAttrRa.
40075 + NameLength)) == NULL)
40077 + zlog_err ("cannot allocate memory %s %d", __FILE__, __LINE__);
40078 + return E_ERR;
40080 + memset (pRsvpPkt->SessionAttributes.u.SessAttrRa.SessionName, 0,
40081 + sizeof (char) *
40082 + pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength);
40083 + strncpy (pRsvpPkt->SessionAttributes.u.SessAttrRa.SessionName, pP,
40084 + pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength);
40085 + pP += pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength;
40086 + *ppData = pP;
40089 + else
40091 + zlog_err ("unknown session attributes object class type %d",
40092 + pObjHdr->CType);
40093 + return E_ERR;
40095 + zlog_debug ("Session Attributes");
40096 + return E_OK;
40099 +E_RC
40100 +SenderTSpecDecoder (void **ppData, RSVP_PKT * pRsvpPkt, OBJ_HDR * pObjHdr,
40101 + uns32 RemainingLen)
40103 + pRsvpPkt->SenderTSpec.MessageHdr.VersionResvd =
40104 + decode_16bit ((uns8 **) ppData);
40105 + pRsvpPkt->SenderTSpec.MessageHdr.MessageLength =
40106 + decode_16bit ((uns8 **) ppData);
40107 + pRsvpPkt->SenderTSpec.ServHdr.ServHdr = decode_8bit ((uns8 **) ppData);
40108 + pRsvpPkt->SenderTSpec.ServHdr.Resvd = decode_8bit ((uns8 **) ppData);
40109 + pRsvpPkt->SenderTSpec.ServHdr.ServLength = decode_16bit ((uns8 **) ppData);
40110 + pRsvpPkt->SenderTSpec.ParamHdr.ParamID = decode_8bit ((uns8 **) ppData);
40111 + pRsvpPkt->SenderTSpec.ParamHdr.ParamFlags = decode_8bit ((uns8 **) ppData);
40112 + pRsvpPkt->SenderTSpec.ParamHdr.ParamLength =
40113 + decode_16bit ((uns8 **) ppData);
40114 + pRsvpPkt->SenderTSpec.TockenBucketRate = decode_float ((uns8 **) ppData);
40115 + pRsvpPkt->SenderTSpec.TockenBucketSize = decode_float ((uns8 **) ppData);
40116 + pRsvpPkt->SenderTSpec.PeakDataRate = decode_float ((uns8 **) ppData);
40117 + pRsvpPkt->SenderTSpec.MinPolicedUnit = decode_32bit ((uns8 **) ppData);
40118 + pRsvpPkt->SenderTSpec.MaxPacketSize = decode_32bit ((uns8 **) ppData);
40119 + zlog_info ("Sender TSPEC %f %f %f %x %x",
40120 + pRsvpPkt->SenderTSpec.PeakDataRate,
40121 + pRsvpPkt->SenderTSpec.TockenBucketRate,
40122 + pRsvpPkt->SenderTSpec.TockenBucketSize,
40123 + pRsvpPkt->SenderTSpec.MinPolicedUnit,
40124 + pRsvpPkt->SenderTSpec.MaxPacketSize);
40125 + return E_OK;
40128 +E_RC
40129 +RRO_Decoder (void **ppData, RSVP_PKT * pRsvpPkt, OBJ_HDR * pObjHdr,
40130 + uns32 RemainingLen)
40132 + int Count;
40133 + RR_SUBOBJ *pRrSubObj, *pPrev = NULL;
40134 + int Len = pObjHdr->Length - sizeof (OBJ_HDR);
40135 + if (Len % 8)
40137 + zlog_err (" the length is not 8-alligned");
40139 + Count = Len / 8;
40140 + while (Len > 0)
40142 + if ((pRrSubObj =
40143 + (RR_SUBOBJ *) XMALLOC (MTYPE_RSVP, sizeof (RR_SUBOBJ))) == NULL)
40145 + zlog_err (" malloc failed ");
40146 + return E_ERR;
40148 + memset (pRrSubObj, 0, sizeof (RR_SUBOBJ));
40149 + if (pRsvpPkt->ReceivedRro.rr == NULL)
40151 + pRsvpPkt->ReceivedRro.rr = pRrSubObj;
40153 + else
40155 + pPrev->next = pRrSubObj;
40157 + pRrSubObj->SubObjHdr.Type = decode_8bit ((uns8 **) ppData);
40158 + pRrSubObj->SubObjHdr.Length = decode_8bit ((uns8 **) ppData);
40159 + Len -= 8;
40160 + if (pRrSubObj->SubObjHdr.Length != 8)
40162 + zlog_err (" the length of subobject is not 8!!!");
40163 + return E_ERR;
40165 + switch (pRrSubObj->SubObjHdr.Type)
40167 + case RRO_SUBTYPE_IPV4:
40168 + pRrSubObj->u.Ipv4.IpAddr = decode_32bit ((uns8 **) ppData);
40169 + pRrSubObj->u.Ipv4.PrefixLen = decode_8bit ((uns8 **) ppData);
40170 + pRrSubObj->u.Ipv4.Flags = decode_8bit ((uns8 **) ppData);
40171 + zlog_info ("RRO subobject: IP %x prefix length %x",
40172 + pRrSubObj->u.Ipv4.IpAddr, pRrSubObj->u.Ipv4.PrefixLen);
40173 + break;
40174 + case RRO_SUBTYPE_LABEL:
40175 + pRrSubObj->u.Label.Flags = decode_8bit ((uns8 **) ppData);
40176 + pRrSubObj->u.Label.CType = decode_8bit ((uns8 **) ppData);
40177 + pRrSubObj->u.Label.Label = decode_32bit ((uns8 **) ppData);
40178 + zlog_info ("RRO subobject: Flags %x CType %x Label %x",
40179 + pRrSubObj->u.Label.Flags, pRrSubObj->u.Label.CType,
40180 + pRrSubObj->u.Label.Label);
40181 + break;
40182 + default:
40183 + zlog_err ("the type %d of subobject is unknown %s %d",
40184 + pRrSubObj->SubObjHdr.Type, __FILE__, __LINE__);
40185 + return E_ERR;
40187 + pPrev = pRrSubObj;
40189 + return E_OK;
40192 +E_RC
40193 +AdSpecDecoder (void **ppData, RSVP_PKT * pRsvpPkt, OBJ_HDR * pObjHdr,
40194 + uns32 RemainingLen)
40196 + pRsvpPkt->ReceivedAdSpec.Resvd = decode_16bit ((uns8 **) ppData);
40197 + pRsvpPkt->ReceivedAdSpec.MsgLen = decode_16bit ((uns8 **) ppData);
40199 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.PerServHdr.PerServHdr =
40200 + decode_8bit ((uns8 **) ppData);
40201 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.PerServHdr.BreakBitAndResvd =
40202 + decode_8bit ((uns8 **) ppData);
40203 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.PerServHdr.Length =
40204 + decode_16bit ((uns8 **) ppData);
40206 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param4Hdr.ParamID =
40207 + decode_8bit ((uns8 **) ppData);
40208 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param4Hdr.ParamFlags =
40209 + decode_8bit ((uns8 **) ppData);
40210 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param4Hdr.ParamLength =
40211 + decode_16bit ((uns8 **) ppData);
40212 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.IS_HopCount =
40213 + decode_32bit ((uns8 **) ppData);
40215 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param6Hdr.ParamID =
40216 + decode_8bit ((uns8 **) ppData);
40217 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param6Hdr.ParamFlags =
40218 + decode_8bit ((uns8 **) ppData);
40219 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param6Hdr.ParamLength =
40220 + decode_16bit ((uns8 **) ppData);
40221 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.PathBW = decode_float ((uns8 **) ppData);
40222 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param8Hdr.ParamID =
40223 + decode_8bit ((uns8 **) ppData);
40224 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param8Hdr.ParamFlags =
40225 + decode_8bit ((uns8 **) ppData);
40226 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param8Hdr.ParamLength =
40227 + decode_16bit ((uns8 **) ppData);
40228 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.MinPathLatency =
40229 + decode_32bit ((uns8 **) ppData);
40230 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param10Hdr.ParamID =
40231 + decode_8bit ((uns8 **) ppData);
40232 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param10Hdr.ParamFlags =
40233 + decode_8bit ((uns8 **) ppData);
40234 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param10Hdr.ParamLength =
40235 + decode_16bit ((uns8 **) ppData);
40236 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.ComposedMTU =
40237 + decode_32bit ((uns8 **) ppData);
40239 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.PerServHdr.PerServHdr =
40240 + decode_8bit ((uns8 **) ppData);
40241 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.PerServHdr.BreakBitAndResvd =
40242 + decode_8bit ((uns8 **) ppData);
40243 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.PerServHdr.Length =
40244 + decode_16bit ((uns8 **) ppData);
40246 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param133Hdr.ParamID =
40247 + decode_8bit ((uns8 **) ppData);
40248 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param133Hdr.ParamFlags =
40249 + decode_8bit ((uns8 **) ppData);
40250 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param133Hdr.ParamLength =
40251 + decode_16bit ((uns8 **) ppData);
40252 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Ctot = decode_32bit ((uns8 **) ppData);
40253 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param134Hdr.ParamID =
40254 + decode_8bit ((uns8 **) ppData);
40255 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param134Hdr.ParamFlags =
40256 + decode_8bit ((uns8 **) ppData);
40257 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param134Hdr.ParamLength =
40258 + decode_16bit ((uns8 **) ppData);
40259 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Dtot = decode_32bit ((uns8 **) ppData);
40260 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param135Hdr.ParamID =
40261 + decode_8bit ((uns8 **) ppData);
40262 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param135Hdr.ParamFlags =
40263 + decode_8bit ((uns8 **) ppData);
40264 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param135Hdr.ParamLength =
40265 + decode_16bit ((uns8 **) ppData);
40266 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Csum = decode_32bit ((uns8 **) ppData);
40267 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param136Hdr.ParamID =
40268 + decode_8bit ((uns8 **) ppData);
40269 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param136Hdr.ParamFlags =
40270 + decode_8bit ((uns8 **) ppData);
40271 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param136Hdr.ParamLength =
40272 + decode_16bit ((uns8 **) ppData);
40273 + pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Dsum = decode_32bit ((uns8 **) ppData);
40274 + return E_OK;
40277 +E_RC
40278 +OpaqueObjDecoder (void **ppData, RSVP_PKT * pRsvpPkt, OBJ_HDR * pObjHdr,
40279 + uns32 RemainingLen)
40281 + zlog_warn ("inside of OpaqueObjDecoder");
40282 + if (pObjHdr->ClassNum == INTEGRITY_CLASS)
40284 + if ((pRsvpPkt->pIntegrityObj =
40285 + (INTEGRITY_OBJ *) XMALLOC (MTYPE_RSVP,
40286 + sizeof (OPAQUE_OBJ_LIST))) == NULL)
40288 + return E_ERR;
40290 + memset (pRsvpPkt->pIntegrityObj, 0, sizeof (OPAQUE_OBJ_LIST));
40291 + pRsvpPkt->pIntegrityObj->ObjHdr = *pObjHdr;
40292 + if ((pRsvpPkt->pIntegrityObj->pData =
40293 + (void *) XMALLOC (MTYPE_RSVP,
40294 + pObjHdr->Length - sizeof (OBJ_HDR))) == NULL)
40296 + XFREE (MTYPE_RSVP, pRsvpPkt->pIntegrityObj);
40297 + return E_ERR;
40299 + memcpy (pRsvpPkt->pIntegrityObj->pData, *ppData,
40300 + pObjHdr->Length - sizeof (OBJ_HDR));
40301 + (*((uns8 *) ppData)) += pObjHdr->Length - sizeof (OBJ_HDR);
40303 + else if (pObjHdr->ClassNum == POLICY_DATA_CLASS)
40305 + if ((pRsvpPkt->pPolicyDataObj =
40306 + (POLICY_DATA_OBJ *) XMALLOC (MTYPE_RSVP,
40307 + sizeof (OPAQUE_OBJ_LIST))) == NULL)
40309 + return E_ERR;
40311 + memset (pRsvpPkt->pPolicyDataObj, 0, sizeof (OPAQUE_OBJ_LIST));
40312 + pRsvpPkt->pPolicyDataObj->ObjHdr = *pObjHdr;
40313 + if ((pRsvpPkt->pPolicyDataObj->pData =
40314 + (void *) XMALLOC (MTYPE_RSVP,
40315 + pObjHdr->Length - sizeof (OBJ_HDR))) == NULL)
40317 + XFREE (MTYPE_RSVP, pRsvpPkt->pPolicyDataObj);
40318 + return E_ERR;
40320 + memcpy (pRsvpPkt->pPolicyDataObj->pData, *ppData,
40321 + pObjHdr->Length - sizeof (OBJ_HDR));
40322 + ((*(uns8 *) ppData)) += pObjHdr->Length - sizeof (OBJ_HDR);
40324 + else if ((pObjHdr->ClassNum != 0) && (pObjHdr->Length != 0))
40326 + OPAQUE_OBJ_LIST *pOpaqueObjTail =
40327 + pRsvpPkt->pOpaqueObjList, *pOpaqueObjPrev = NULL;
40328 + if (pOpaqueObjTail != NULL)
40330 + while (pOpaqueObjTail->next != NULL)
40332 + pOpaqueObjTail = pOpaqueObjTail->next;
40335 + if (pOpaqueObjTail != NULL)
40337 + if ((pOpaqueObjTail->next =
40338 + (OPAQUE_OBJ_LIST *) XMALLOC (MTYPE_RSVP,
40339 + sizeof (OPAQUE_OBJ_LIST))) ==
40340 + NULL)
40342 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
40343 + return E_ERR;
40345 + pOpaqueObjPrev = pOpaqueObjTail;
40346 + pOpaqueObjTail = pOpaqueObjTail->next;
40348 + else
40350 + pOpaqueObjTail = pRsvpPkt->pOpaqueObjList =
40351 + (OPAQUE_OBJ_LIST *) XMALLOC (MTYPE_RSVP,
40352 + sizeof (OPAQUE_OBJ_LIST));
40353 + if (pOpaqueObjTail == NULL)
40355 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
40356 + return E_ERR;
40359 + memset (pOpaqueObjTail, 0, sizeof (OPAQUE_OBJ_LIST));
40360 + pOpaqueObjTail->ObjHdr = *pObjHdr;
40361 + if ((pOpaqueObjTail->pData =
40362 + (void *) XMALLOC (MTYPE_RSVP,
40363 + pObjHdr->Length - sizeof (OBJ_HDR))) == NULL)
40365 + if (pOpaqueObjPrev == NULL)
40367 + pRsvpPkt->pOpaqueObjList = NULL;
40369 + else
40371 + pOpaqueObjPrev->next = NULL;
40373 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
40374 + XFREE (MTYPE_RSVP, pOpaqueObjTail);
40375 + return E_ERR;
40377 + memcpy (pOpaqueObjTail->pData, *ppData,
40378 + pObjHdr->Length - sizeof (OBJ_HDR));
40379 + ((*(uns8 *) ppData)) += pObjHdr->Length - sizeof (OBJ_HDR);
40381 + return E_OK;
40384 +E_RC
40385 +FlowSpecDecoder (void **ppData, FLOW_SPEC_OBJ * pFlowSpec)
40387 + pFlowSpec->MsgHdr.VersionResvd = decode_16bit ((uns8 **) ppData);
40388 + pFlowSpec->MsgHdr.MessageLength = decode_16bit ((uns8 **) ppData);
40389 + pFlowSpec->ServHdr.ServHdr = decode_8bit ((uns8 **) ppData);
40390 + pFlowSpec->ServHdr.Resvd = decode_8bit ((uns8 **) ppData);
40391 + pFlowSpec->ServHdr.ServLength = decode_16bit ((uns8 **) ppData);
40392 + pFlowSpec->ParamHdr.ParamID = decode_8bit ((uns8 **) ppData);
40393 + pFlowSpec->ParamHdr.ParamFlags = decode_8bit ((uns8 **) ppData);
40394 + pFlowSpec->ParamHdr.ParamLength = decode_16bit ((uns8 **) ppData);
40395 + if (pFlowSpec->ServHdr.ServHdr == FLOW_SPEC_CTRL_LOAD_SERV_NUMBER)
40397 + pFlowSpec->u.CtrlLoad.TockenBucketRate =
40398 + decode_float ((uns8 **) ppData);
40399 + pFlowSpec->u.CtrlLoad.TockenBucketSize =
40400 + decode_float ((uns8 **) ppData);
40401 + pFlowSpec->u.CtrlLoad.PeakDataRate = decode_float ((uns8 **) ppData);
40402 + zlog_info ("FLOW_SPEC - data rate %f",
40403 + pFlowSpec->u.CtrlLoad.PeakDataRate);
40404 + pFlowSpec->u.CtrlLoad.MinPolicedUnit = decode_float ((uns8 **) ppData);
40405 + pFlowSpec->u.CtrlLoad.MaxPacketSize = decode_float ((uns8 **) ppData);
40407 + else if (pFlowSpec->ServHdr.ServHdr == FLOW_SPEC_GUAR_SERV_NUMBER)
40409 + pFlowSpec->u.Guar.CtrlLoad.TockenBucketRate =
40410 + decode_float ((uns8 **) ppData);
40411 + pFlowSpec->u.Guar.CtrlLoad.TockenBucketSize =
40412 + decode_float ((uns8 **) ppData);
40413 + pFlowSpec->u.Guar.CtrlLoad.PeakDataRate =
40414 + decode_float ((uns8 **) ppData);
40415 + zlog_info ("FLOW_SPEC1 - data rate %f",
40416 + pFlowSpec->u.Guar.CtrlLoad.PeakDataRate);
40417 + pFlowSpec->u.Guar.CtrlLoad.MinPolicedUnit =
40418 + decode_float ((uns8 **) ppData);
40419 + pFlowSpec->u.Guar.CtrlLoad.MaxPacketSize =
40420 + decode_float ((uns8 **) ppData);
40421 + pFlowSpec->u.Guar.GuarSpecificParamHdr.ParamID =
40422 + decode_8bit ((uns8 **) ppData);
40423 + pFlowSpec->u.Guar.GuarSpecificParamHdr.ParamFlags =
40424 + decode_8bit ((uns8 **) ppData);
40425 + pFlowSpec->u.Guar.GuarSpecificParamHdr.ParamLength =
40426 + decode_16bit ((uns8 **) ppData);
40427 + pFlowSpec->u.Guar.Rate = decode_float ((uns8 **) ppData);
40428 + pFlowSpec->u.Guar.SlackTerm = decode_32bit ((uns8 **) ppData);
40430 + else
40432 + zlog_err ("Unknown FlowSpec %d", pFlowSpec->ServHdr.ServHdr);
40433 + return E_ERR;
40435 + return E_OK;
40438 +E_RC
40439 +FilterSpecDecoder (void **ppData, FILTER_SPEC_OBJ * pFilterSpec)
40441 + pFilterSpec->IpAddr = decode_32bit ((uns8 **) ppData);
40442 + pFilterSpec->Resvd = decode_16bit ((uns8 **) ppData);
40443 + pFilterSpec->LspId = decode_16bit ((uns8 **) ppData);
40444 + zlog_info ("FILTER_SPEC %x %x", pFilterSpec->IpAddr, pFilterSpec->LspId);
40445 + return E_OK;
40448 +E_RC
40449 +LabelDecoder (void **ppData, LABEL_OBJ * pLabelObj)
40451 + pLabelObj->Label = decode_32bit ((uns8 **) ppData);
40452 + zlog_info ("label decoded %x", pLabelObj->Label);
40453 + return E_OK;
40456 +E_RC
40457 +FlowDescriptorDecoder (void **ppData, RSVP_PKT * pRsvpPkt, uns32 RemainingLen)
40459 + FLOW_SPEC_OBJ *pFlowSpecObj, FlowSpec;
40460 + FILTER_LIST *pFilterListTail = NULL, *pFilterListNew;
40461 + FILTER_SPEC_DATA *pFilterSpecData = NULL;
40462 + OBJ_HDR *pObjHdr;
40463 + enum FlowDescrDecodeStates
40465 + FLOW_SPEC_DECODED,
40466 + FILTER_SPEC_DECODED,
40467 + LABEL_DECODED,
40468 + OPAQ_DECODED
40469 + } State;
40471 + memset (&FlowSpec, 0, sizeof (FLOW_SPEC_OBJ));
40472 + pFlowSpecObj = &FlowSpec;
40474 + DECODE_OBJ_HDR if (pObjHdr->ClassNum != FLOW_SPEC_CLASS)
40476 + if (pObjHdr->ClassNum == FILTER_SPEC_CLASS)
40478 + (*(char *) ppData) -= sizeof (OBJ_HDR);
40479 + goto flow_spec_missing;
40481 + zlog_err ("Expected flowspec is not found");
40482 + return E_ERR;
40484 + if (FlowSpecDecoder (ppData, pFlowSpecObj) != E_OK)
40486 + zlog_err ("Cannot decode FlowSpec");
40487 + return E_ERR;
40489 +flow_spec_missing:
40491 + State = FLOW_SPEC_DECODED;
40492 + RemainingLen -= pObjHdr->Length;
40493 + while (RemainingLen)
40495 + DECODE_OBJ_HDR switch (pObjHdr->ClassNum)
40497 + case FILTER_SPEC_CLASS:
40498 + if (State == OPAQ_DECODED)
40500 + zlog_err ("FILTER_SPEC after OPAQ");
40501 + return E_ERR;
40503 + if ((pFilterListNew =
40504 + (FILTER_LIST *) XMALLOC (MTYPE_RSVP,
40505 + sizeof (FILTER_LIST))) == NULL)
40507 + zlog_err ("Memory allocation failed %s %d", __FILE__, __LINE__);
40508 + return E_ERR;
40510 + if ((pFilterSpecData =
40511 + (FILTER_SPEC_DATA *) XMALLOC (MTYPE_RSVP,
40512 + sizeof (FILTER_SPEC_DATA))) ==
40513 + NULL)
40515 + zlog_err ("Memory allocation failed %s %d", __FILE__, __LINE__);
40516 + XFREE (MTYPE_RSVP, pFilterListNew);
40517 + return E_ERR;
40519 + pFilterListNew->pFilterSpecData = pFilterSpecData;
40520 + if (FilterSpecDecoder (ppData, &pFilterSpecData->FilterSpec) !=
40521 + E_OK)
40523 + zlog_err ("Cannot decode filter spec");
40524 + XFREE (MTYPE_RSVP, pFilterSpecData);
40525 + XFREE (MTYPE_RSVP, pFilterListNew);
40526 + return E_ERR;
40528 + memcpy (&pFilterSpecData->NewFlowSpec, pFlowSpecObj,
40529 + sizeof (FLOW_SPEC_OBJ));
40530 + pFilterSpecData->NewFlowSpecValid = 1;
40531 + if (pFilterListTail == NULL)
40533 + pFilterListTail = pRsvpPkt->pFilterList = pFilterListNew;
40535 + else
40537 + pFilterListTail->next = pFilterListNew;
40538 + pFilterListTail = pFilterListTail->next;
40540 + State = FILTER_SPEC_DECODED;
40541 + break;
40542 + case LABEL_CLASS:
40543 + if (State != FILTER_SPEC_DECODED)
40545 + zlog_err ("Label is not after FILTER_SPEC");
40546 + return E_ERR;
40548 + if (LabelDecoder (ppData, &pFilterSpecData->ReceivedLabel) != E_OK)
40550 + zlog_err ("Cannot decode Label");
40551 + return E_ERR;
40553 + State = LABEL_DECODED;
40554 + break;
40555 + case RECORDED_ROUTE_CLASS:
40556 + if (State != LABEL_DECODED)
40558 + zlog_err ("RRO is not after LABEL");
40559 + return E_ERR;
40561 + if (RRO_Decoder (ppData, pRsvpPkt, pObjHdr, RemainingLen) != E_OK)
40563 + zlog_err ("Cannot decode RRO");
40564 + return E_ERR;
40566 + pFilterSpecData->Rro.rr = pRsvpPkt->ReceivedRro.rr;
40567 + pRsvpPkt->ReceivedRro.rr = NULL;
40568 + break;
40569 + case FLOW_SPEC_CLASS:
40570 + if (State == FLOW_SPEC_DECODED)
40572 + zlog_err ("FLOW_SPEC is after FLOW_SPEC");
40573 + return E_ERR;
40575 + if (pRsvpPkt->Style.OptionVector2 != FF_STYLE_BITS)
40577 + zlog_err ("while SE style, FLOW_SPEC is already decoded");
40578 + return E_ERR;
40580 + if (FlowSpecDecoder (ppData, pFlowSpecObj) != E_OK)
40582 + zlog_err ("Cannot decode FlowSpec");
40583 + return E_ERR;
40585 + State = FLOW_SPEC_DECODED;
40586 + break;
40587 + default:
40588 + zlog_err ("object of unknown type %x %s %d", pObjHdr->ClassNum,
40589 + __FILE__, __LINE__);
40590 + (*(uns8 *) ppData) -= 4;
40591 + return E_OK;
40592 + /*if(OpaqueObjDecoder(ppData,pRsvpPkt,pObjHdr) != E_OK)
40594 + zlog_err("Cannot decode OPAQUE object");
40595 + return E_ERR;
40597 + State = OPAQ_DECODED; */
40599 + RemainingLen -= pObjHdr->Length;
40601 + return E_OK;
40604 +E_RC
40605 +StyleDecoder (void **ppData, RSVP_PKT * pRsvpPkt, OBJ_HDR * pObjHdr,
40606 + uns32 RemainingLen)
40608 + pRsvpPkt->Style.Flags = decode_8bit ((uns8 **) ppData);
40609 + pRsvpPkt->Style.OptionVector1 = decode_8bit ((uns8 **) ppData);
40610 + pRsvpPkt->Style.OptionVector2 = decode_16bit ((uns8 **) ppData);
40611 + zlog_info ("Style %x %x %x", pRsvpPkt->Style.Flags,
40612 + pRsvpPkt->Style.OptionVector1, pRsvpPkt->Style.OptionVector2);
40613 + return FlowDescriptorDecoder (ppData, pRsvpPkt, RemainingLen - 4);
40616 +E_RC
40617 +ErrSpecDecoder (void **ppData, RSVP_PKT * pRsvpPkt, OBJ_HDR * pObjHdr,
40618 + uns32 RemainingLen)
40620 + pRsvpPkt->ErrorSpec.IpAddr = decode_32bit ((uns8 **) ppData);
40621 + pRsvpPkt->ErrorSpec.Flags = decode_8bit ((uns8 **) ppData);
40622 + pRsvpPkt->ErrorSpec.ErrCode = decode_8bit ((uns8 **) ppData);
40623 + pRsvpPkt->ErrorSpec.ErrVal = decode_16bit ((uns8 **) ppData);
40624 + return E_OK;
40627 +void
40628 +InitRsvpDecoder ()
40630 + memset (DecodeHandlers, 0, sizeof (DECODE_HANDLER) * (MAX_OBJS));
40631 + DecodeHandlers[SESSION_CLASS].pObjDecoder = SessionDecoder;
40632 + DecodeHandlers[RSVP_HOP_CLASS].pObjDecoder = RsvpHopDecoder;
40633 + DecodeHandlers[TIME_VALUES_CLASS].pObjDecoder = TimeValuesDecoder;
40634 + DecodeHandlers[SENDER_TEMPLATE_CLASS].pObjDecoder = SenderTemplateDecoder;
40635 + DecodeHandlers[LABEL_REQUEST_CLASS].pObjDecoder = LabelReqDecoder;
40636 + DecodeHandlers[EXPLICIT_ROUTE_CLASS].pObjDecoder = ERO_Decoder;
40637 + DecodeHandlers[SESSION_ATTRIBUTE_CLASS].pObjDecoder = SessionAttrDecoder;
40638 + DecodeHandlers[SENDER_TSPEC_CLASS].pObjDecoder = SenderTSpecDecoder;
40639 + DecodeHandlers[RECORDED_ROUTE_CLASS].pObjDecoder = RRO_Decoder;
40640 + DecodeHandlers[ADSPEC_CLASS].pObjDecoder = AdSpecDecoder;
40641 + DecodeHandlers[STYLE_CLASS].pObjDecoder = StyleDecoder;
40642 + DecodeHandlers[POLICY_DATA_CLASS].pObjDecoder = OpaqueObjDecoder;
40643 + DecodeHandlers[INTEGRITY_CLASS].pObjDecoder = OpaqueObjDecoder;
40644 + DecodeHandlers[ERR_SPEC_CLASS].pObjDecoder = ErrSpecDecoder;
40647 +E_RC
40648 +DecodeAndProcessRsvpMsg (void *pPkt, int PktLen, uns32 IfIndex,
40649 + IPV4_ADDR SrcIpAddr)
40651 + RSVP_COMMON_HDR RsvpCommonHdr;
40652 + RSVP_PKT *pRsvpPkt;
40653 + uns8 *pData = pPkt;
40654 + void **ppData;
40655 + OBJ_HDR *pObjHdr;
40656 + uns32 InitialAddress = (uns32) pData;
40657 + uns16 CheckSum = 0;
40659 + if ((pRsvpPkt =
40660 + (RSVP_PKT *) XMALLOC (MTYPE_RSVP, sizeof (RSVP_PKT))) == NULL)
40662 + zlog_err ("memory allocation failed %s %d", __FILE__, __LINE__);
40663 + return E_ERR;
40665 + memset (pRsvpPkt, 0, sizeof (RSVP_PKT));
40667 + DECODE_COMMON_HDR if ((RsvpCommonHdr.VersionFlags & 0xF0) != RSVP_VERSION)
40669 + zlog_err (" wrong RSVP version %d %d", RsvpCommonHdr.VersionFlags,
40670 + RsvpCommonHdr.MsgType);
40672 + else
40674 + zlog_debug ("RSVP message of right version");
40675 + rsvp_calc_pkt_cksum (pPkt, PktLen, &CheckSum);
40676 + if (RsvpCommonHdr.CheckSum != CheckSum)
40678 + printf ("received checksum %x calculated %x\n",
40679 + RsvpCommonHdr.CheckSum, CheckSum);
40681 + else
40683 + //zlog_info("received checksum is OK");
40686 + //PktLen -= sizeof(RSVP_COMMON_HDR);
40688 + while (((uns32) pData - InitialAddress) < PktLen)
40690 + ppData = (void **) &pData;
40691 + DECODE_OBJ_HDR
40692 + if (DecodeHandlers[pObjHdr->ClassNum].pObjDecoder != NULL)
40694 + if (DecodeHandlers[pObjHdr->ClassNum].pObjDecoder (ppData,
40695 + pRsvpPkt,
40696 + pObjHdr,
40697 + (PktLen -
40698 + ((uns32) pData -
40699 + InitialAddress)))
40700 + != E_OK)
40702 + zlog_err ("Object decoding failed");
40704 + else
40706 + //zlog_debug("Object decoded");
40709 + else
40711 + //zlog_warn("The object of class type %d is not supported %d",pObjHdr->ClassNum,pObjHdr->Length);
40712 + //((char *)pData) += pObjHdr->Length;
40713 + OpaqueObjDecoder (ppData, pRsvpPkt, pObjHdr,
40714 + (PktLen - ((uns32) pData - InitialAddress)));
40717 + switch (RsvpCommonHdr.MsgType)
40719 + case PATH_MSG:
40720 + DumpPathMsg (pRsvpPkt, NULL);
40721 + if (ProcessRsvpPathMessage
40722 + (pRsvpPkt, IfIndex, SrcIpAddr, RsvpCommonHdr.SendTTL) != E_OK)
40724 + zlog_err ("RSVP PATH message processing failed");
40726 + break;
40727 + case RESV_MSG:
40728 + DumpResvMsg (pRsvpPkt, NULL);
40729 + if (ProcessRsvpResvMessage (pRsvpPkt) != E_OK)
40731 + zlog_err ("An error on RESV processing");
40733 + break;
40734 + case PATH_ERR_MSG:
40735 + DumpPathErrMsg (pRsvpPkt, NULL);
40736 + if (ProcessRsvpPathErrMessage
40737 + (pRsvpPkt, IfIndex, SrcIpAddr, RsvpCommonHdr.SendTTL) != E_OK)
40739 + zlog_err ("An error on PATH_ERR processing");
40741 + break;
40742 + case RESV_ERR_MSG:
40743 + DumpResvErrMsg (pRsvpPkt, NULL);
40744 + if (ProcessRsvpResvErrMessage (pRsvpPkt) != E_OK)
40746 + zlog_err ("An error on RESV ERR message processing");
40748 + break;
40749 + case PATH_TEAR_MSG:
40750 + DumpPathTearMsg (pRsvpPkt, NULL);
40751 + if (ProcessRsvpPathTearMessage
40752 + (pRsvpPkt, IfIndex, SrcIpAddr, RsvpCommonHdr.SendTTL) != E_OK)
40754 + zlog_err ("An error on PATH_TEAR processing");
40756 + break;
40757 + case RESV_TEAR_MSG:
40758 + DumpResvTearMsg (pRsvpPkt, NULL);
40759 + if (ProcessRsvpResvTearMessage (pRsvpPkt) != E_OK)
40761 + zlog_err ("An error on RESV_TEAR processing");
40763 + break;
40764 + case RESV_CONF_MSG:
40765 + zlog_warn ("RESV Conf message is not supported");
40766 + break;
40767 + default:
40768 + zlog_err ("RSVP message of unknown type is received");
40770 + //FreeRsvpPkt(&RsvpPkt);
40771 + return E_OK;
40773 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_decode.h quagga-mpls/rsvpd/rsvp_decode.h
40774 --- quagga/rsvpd/rsvp_decode.h 1969-12-31 18:00:00.000000000 -0600
40775 +++ quagga-mpls/rsvpd/rsvp_decode.h 2007-06-14 21:35:58.000000000 -0500
40776 @@ -0,0 +1,7 @@
40777 +#ifndef __RSVP_DECODE_H_
40778 +#define __RSVP_DECODE_H_
40780 +E_RC DecodeAndProcessRsvpMsg (void *pPkt, int PktLen, uns32 IfIndex,
40781 + IPV4_ADDR SrcIpAddr);
40782 +void InitRsvpDecoder ();
40783 +#endif
40784 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_encode.c quagga-mpls/rsvpd/rsvp_encode.c
40785 --- quagga/rsvpd/rsvp_encode.c 1969-12-31 18:00:00.000000000 -0600
40786 +++ quagga-mpls/rsvpd/rsvp_encode.c 2007-07-02 22:50:59.000000000 -0500
40787 @@ -0,0 +1,864 @@
40788 +/* Module: rsvp_encode.c
40789 + Contains: RSVP packet encoding functions which make
40790 + the packet ready to send.
40791 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
40792 + */
40794 +#include "rsvp.h"
40796 +void
40797 +encode_32bit (uns8 ** stream, uns32 val)
40799 + *(*stream)++ = (uns8) (val >> 24);
40800 + *(*stream)++ = (uns8) (val >> 16);
40801 + *(*stream)++ = (uns8) (val >> 8);
40802 + *(*stream)++ = (uns8) (val);
40805 +void
40806 +encode_24bit (uns8 ** stream, uns32 val)
40808 + *(*stream)++ = (uns8) (val >> 16);
40809 + *(*stream)++ = (uns8) (val >> 8);
40810 + *(*stream)++ = (uns8) (val);
40814 +void
40815 +encode_16bit (uns8 ** stream, uns32 val)
40817 + *(*stream)++ = (uns8) (val >> 8);
40818 + *(*stream)++ = (uns8) (val);
40822 +void
40823 +encode_8bit (uns8 ** stream, uns32 val)
40825 + *(*stream)++ = (uns8) (val);
40828 +void
40829 +encode_float (uns8 ** stream, float f)
40831 + *((uns32 *) (*stream)) = htonl (*((uns32 *) & (f)));
40832 + (*stream) += 4;
40835 +void
40836 +rsvp_calc_pkt_cksum (char *u, unsigned int PktLen, uns16 * const pCksum)
40838 + uns32 Cksum32;
40839 + unsigned int Offset;
40841 + uns8 *p8;
40843 + Cksum32 = 0;
40844 + Offset = 0;
40845 + while (PktLen > 1)
40847 + p8 = (uns8 *) (u + Offset);
40849 + if (Offset != 2) /* Offset 2 is the checksum word. We don't add this in */
40851 + Cksum32 += (uns32) ntohs (*((uns16 *) p8));
40852 + if ((Cksum32 & 0x80000000) != 0)
40853 + Cksum32 = (Cksum32 & 0xFFFF) + (Cksum32 >> 16);
40855 + Offset += 2;
40856 + PktLen -= 2;
40859 + if (PktLen > 0) /* Odd length? */
40861 + p8 = (uns8 *) (u + Offset);
40863 + Cksum32 += (uns32) * p8;
40866 + while ((Cksum32 >> 16) != 0)
40867 + Cksum32 = (Cksum32 & 0xFFFF) + (Cksum32 >> 16);
40869 + *pCksum = (uns16) (~Cksum32);
40872 +static char BigBuffer[1500];
40874 +#define ENCODE_COMMON_HDR(VersionFlags,MsgType,CheckSum,SendTTL,Resvd,RsvpLength) \
40876 + encode_8bit((uns8 **)ppData,VersionFlags); /* VersionFlags */ \
40877 + encode_8bit((uns8 **)ppData,MsgType);/* MsgType */ \
40878 + pCheckSum = (uns16 *)(*ppData); \
40879 + encode_16bit((uns8 **)ppData,CheckSum);/* CheckSum */ \
40880 + encode_8bit((uns8 **)ppData,SendTTL);/* SendTTL */ \
40881 + encode_8bit((uns8 **)ppData,Resvd);/* Resvd */ \
40882 + pRsvpLength = (uns16*)(*ppData); \
40883 + encode_16bit((uns8 **)ppData,RsvpLength);/* RsvpLength */\
40884 + PktLen += 8; \
40887 +#define ENCODE_OBJ_HDR(Length,ClassNum,CType) \
40889 + pVariableLengthObj = (uns16 *)*ppData; \
40890 + encode_16bit((uns8 **)ppData,Length); /* Length */\
40891 + encode_8bit((uns8 **)ppData,ClassNum);/* ClassNum */\
40892 + encode_8bit((uns8 **)ppData,CType);/* CType */\
40893 + zlog_info("obj %d ctype %d len %d",ClassNum,CType,Length);\
40894 + PktLen += 4; \
40897 +#define ENCODE_SESSION \
40899 + encode_32bit((uns8 **)ppData,pRsvpPkt->Session.Dest);\
40900 + encode_16bit((uns8 **)ppData,pRsvpPkt->Session.Resvd);\
40901 + encode_16bit((uns8 **)ppData,pRsvpPkt->Session.TunnelId);\
40902 + encode_32bit((uns8 **)ppData,pRsvpPkt->Session.ExtTunelId);\
40903 + PktLen += 12; \
40906 +#define ENCODE_RSVP_HOP \
40908 + encode_32bit((uns8 **)ppData,pRsvpPkt->SentRsvpHop.PHop); \
40909 + encode_32bit((uns8 **)ppData,pRsvpPkt->SentRsvpHop.LIH); \
40910 + PktLen += 8; \
40913 +#define ENCODE_TIME_VALUES \
40914 +{ \
40915 + encode_32bit((uns8 **)ppData,pRsvpPkt->TimeValues.TimeValues); \
40916 + PktLen += 4; \
40919 +#define ENCODE_STYLE \
40920 +{ \
40921 + encode_8bit((uns8 **)ppData,pRsvpPkt->Style.Flags); \
40922 + encode_8bit((uns8 **)ppData,pRsvpPkt->Style.OptionVector1); \
40923 + encode_16bit((uns8 **)ppData,pRsvpPkt->Style.OptionVector2); \
40924 + PktLen += 4; \
40927 +#define ENCODE_SENDER_TEMPLATE \
40928 +{ \
40929 + encode_32bit((uns8 **)ppData,pRsvpPkt->SenderTemplate.IpAddr); \
40930 + encode_16bit((uns8 **)ppData,pRsvpPkt->SenderTemplate.Resvd); \
40931 + encode_16bit((uns8 **)ppData,pRsvpPkt->SenderTemplate.LspId); \
40932 + PktLen += 8; \
40935 +#define ENCODE_LABEL_REQUEST \
40936 +{ \
40937 + encode_16bit((uns8 **)ppData,pRsvpPkt->LabelRequest.Resvd); \
40938 + encode_16bit((uns8 **)ppData,pRsvpPkt->LabelRequest.L3Pid); \
40939 + PktLen += 4; \
40942 +#define ENCODE_ERO \
40943 +{ \
40944 + ER_SUBOBJ *pErSubObj = pRsvpPkt->ReceivedEro.er;\
40945 + VariableLengthObj = sizeof(OBJ_HDR); /* for obj header */ \
40946 + while(pErSubObj != NULL) \
40947 + { \
40948 + zlog_info("encoding of %x",pErSubObj->u.Ipv4.IpAddress);\
40949 + encode_8bit((uns8 **)ppData,pErSubObj->SubObjHdr.LType);\
40950 + encode_8bit((uns8 **)ppData,pErSubObj->SubObjHdr.Length);\
40951 + PktLen += 2; \
40952 + VariableLengthObj += 2; \
40953 + switch(pErSubObj->SubObjHdr.LType & 0x7F) \
40954 + {\
40955 + case ERO_SUBTYPE_IPV4:\
40956 + encode_32bit((uns8 **)ppData,pErSubObj->u.Ipv4.IpAddress);\
40957 + encode_8bit((uns8 **)ppData,pErSubObj->u.Ipv4.PrefixLength);\
40958 + encode_8bit((uns8 **)ppData,pErSubObj->u.Ipv4.Resvd);\
40959 + VariableLengthObj += 6; \
40960 + PktLen += 6; \
40961 + break;\
40962 + default:\
40963 + zlog_err("the type %d of subobject is unknown %s %d",(pErSubObj->SubObjHdr.LType & 0x7F),__FILE__,__LINE__);\
40964 + return E_ERR;\
40965 + }\
40966 + pErSubObj = pErSubObj->next; \
40967 + }\
40968 + pErSubObj = pRsvpPkt->SentEro.er;\
40969 + while(pErSubObj != NULL)\
40970 + {\
40971 + zlog_info("encoding2 of %x",pErSubObj->u.Ipv4.IpAddress);\
40972 + encode_8bit((uns8 **)ppData,pErSubObj->SubObjHdr.LType);\
40973 + encode_8bit((uns8 **)ppData,pErSubObj->SubObjHdr.Length);\
40974 + PktLen += 2; \
40975 + VariableLengthObj += 2; \
40976 + switch(pErSubObj->SubObjHdr.LType & 0x7F)\
40977 + {\
40978 + case ERO_SUBTYPE_IPV4:\
40979 + encode_32bit((uns8 **)ppData,pErSubObj->u.Ipv4.IpAddress);\
40980 + encode_8bit((uns8 **)ppData,pErSubObj->u.Ipv4.PrefixLength);\
40981 + encode_8bit((uns8 **)ppData,pErSubObj->u.Ipv4.Resvd);\
40982 + PktLen += 6; \
40983 + VariableLengthObj += 6; \
40984 + break;\
40985 + default:\
40986 + zlog_err("the type %d of subobject is unknown %s %d",(pErSubObj->SubObjHdr.LType & 0x7F),__FILE__,__LINE__);\
40987 + return E_ERR;\
40988 + }\
40989 + pErSubObj = pErSubObj->next; \
40990 + }\
40993 +#define ENCODE_SESSION_ATTRIBUTES \
40994 +{ \
40995 + VariableLengthObj = sizeof(OBJ_HDR); /* for obj header */ \
40996 + if(pRsvpPkt->SessionAttributes.CType == SESSION_ATTRIBUTES_CLASS_TYPE) \
40997 + { \
40998 + encode_8bit((uns8 **)ppData,pRsvpPkt->SessionAttributes.u.SessAttr.SetPrio); \
40999 + encode_8bit((uns8 **)ppData,pRsvpPkt->SessionAttributes.u.SessAttr.HoldPrio); \
41000 + encode_8bit((uns8 **)ppData,pRsvpPkt->SessionAttributes.u.SessAttr.Flags); \
41001 + encode_8bit((uns8 **)ppData,pRsvpPkt->SessionAttributes.u.SessAttr.NameLength); \
41002 + PktLen += 4; \
41003 + VariableLengthObj += 4; \
41004 + if(pRsvpPkt->SessionAttributes.u.SessAttr.NameLength % 4) \
41005 + { \
41006 + zlog_err("Session name length is %d must be multiple of 4",pRsvpPkt->SessionAttributes.u.SessAttr.NameLength); \
41007 + } \
41008 + if(pRsvpPkt->SessionAttributes.u.SessAttr.NameLength < 8) \
41009 + { \
41010 + zlog_err("Session name length is %d must be at least 8",pRsvpPkt->SessionAttributes.u.SessAttr.NameLength); \
41011 + }\
41012 + if(pRsvpPkt->SessionAttributes.u.SessAttr.NameLength != 0) \
41013 + { \
41014 + char *pP = *ppData; \
41015 + strncpy(pP,pRsvpPkt->SessionAttributes.u.SessAttr.SessionName,pRsvpPkt->SessionAttributes.u.SessAttr.NameLength); \
41016 + PktLen += pRsvpPkt->SessionAttributes.u.SessAttr.NameLength; \
41017 + pP += pRsvpPkt->SessionAttributes.u.SessAttr.NameLength; \
41018 + *ppData = pP; \
41019 + VariableLengthObj += pRsvpPkt->SessionAttributes.u.SessAttr.NameLength; \
41020 + } \
41021 + } \
41022 + else if(pRsvpPkt->SessionAttributes.CType == SESSION_ATTRIBUTES_RA_CLASS_TYPE) \
41023 + { \
41024 + encode_32bit((uns8 **)ppData,pRsvpPkt->SessionAttributes.u.SessAttrRa.ExcludeAny); \
41025 + encode_32bit((uns8 **)ppData,pRsvpPkt->SessionAttributes.u.SessAttrRa.IncludeAny); \
41026 + encode_32bit((uns8 **)ppData,pRsvpPkt->SessionAttributes.u.SessAttrRa.IncludeAll); \
41027 + encode_8bit((uns8 **)ppData,pRsvpPkt->SessionAttributes.u.SessAttrRa.SetPrio); \
41028 + encode_8bit((uns8 **)ppData,pRsvpPkt->SessionAttributes.u.SessAttrRa.HoldPrio); \
41029 + encode_8bit((uns8 **)ppData,pRsvpPkt->SessionAttributes.u.SessAttrRa.Flags); \
41030 + encode_8bit((uns8 **)ppData,pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength); \
41031 + PktLen += 16; \
41032 + VariableLengthObj += 16; \
41033 + if(pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength % 4) \
41034 + { \
41035 + zlog_err("Session name length is %d must be multiple of 4",pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength); \
41036 + } \
41037 + if(pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength < 8) \
41038 + { \
41039 + zlog_err("Session name length is %d must be at least 8",pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength); \
41040 + } \
41041 + if(pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength != 0) \
41042 + { \
41043 + char *pP = *ppData; \
41044 + strncpy(pP,pRsvpPkt->SessionAttributes.u.SessAttrRa.SessionName,pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength); \
41045 + PktLen += pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength; \
41046 + pP += pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength; \
41047 + *ppData = pP; \
41048 + VariableLengthObj += pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength; \
41049 + } \
41050 + } \
41051 + else \
41052 + { \
41053 + zlog_err("unknown session attributes object class type %d",pRsvpPkt->SessionAttributes.CType); \
41054 + } \
41055 + zlog_debug("Session Attributes"); \
41058 +#define ENCODE_SENDER_TSPEC \
41059 +{ \
41060 + encode_16bit((uns8 **)ppData,pRsvpPkt->SenderTSpec.MessageHdr.VersionResvd); \
41061 + encode_16bit((uns8 **)ppData,pRsvpPkt->SenderTSpec.MessageHdr.MessageLength); \
41062 + encode_8bit((uns8 **)ppData,pRsvpPkt->SenderTSpec.ServHdr.ServHdr); \
41063 + encode_8bit((uns8 **)ppData,pRsvpPkt->SenderTSpec.ServHdr.Resvd); \
41064 + encode_16bit((uns8 **)ppData,pRsvpPkt->SenderTSpec.ServHdr.ServLength); \
41065 + encode_8bit((uns8 **)ppData,pRsvpPkt->SenderTSpec.ParamHdr.ParamID); \
41066 + encode_8bit((uns8 **)ppData,pRsvpPkt->SenderTSpec.ParamHdr.ParamFlags); \
41067 + encode_16bit((uns8 **)ppData,pRsvpPkt->SenderTSpec.ParamHdr.ParamLength); \
41068 + encode_float((uns8 **)ppData,pRsvpPkt->SenderTSpec.TockenBucketRate); \
41069 + encode_float((uns8 **)ppData,pRsvpPkt->SenderTSpec.TockenBucketSize); \
41070 + encode_float((uns8 **)ppData,pRsvpPkt->SenderTSpec.PeakDataRate); \
41071 + encode_32bit((uns8 **)ppData,pRsvpPkt->SenderTSpec.MinPolicedUnit); \
41072 + encode_32bit((uns8 **)ppData,pRsvpPkt->SenderTSpec.MaxPacketSize); \
41073 + PktLen += 32; \
41076 +#define ENCODE_RRO \
41077 +{ \
41078 + RR_SUBOBJ *pRrSubObj = pRsvpPkt->ReceivedRro.rr; \
41079 + VariableLengthObj = sizeof(OBJ_HDR); /* for obj header */ \
41080 + while(pRrSubObj != NULL) \
41081 + { \
41082 + encode_8bit((uns8 **)ppData,pRrSubObj->SubObjHdr.Type); \
41083 + encode_8bit((uns8 **)ppData,pRrSubObj->SubObjHdr.Length); \
41084 + PktLen += 2; \
41085 + VariableLengthObj += 2; \
41086 + if(pRrSubObj->SubObjHdr.Length != 8) \
41087 + { \
41088 + zlog_err(" the length of subobject is not 8!!!"); \
41089 + } \
41090 + switch(pRrSubObj->SubObjHdr.Type) \
41091 + { \
41092 + case RRO_SUBTYPE_IPV4: \
41093 + encode_32bit((uns8 **)ppData,pRrSubObj->u.Ipv4.IpAddr); \
41094 + encode_8bit((uns8 **)ppData,pRrSubObj->u.Ipv4.PrefixLen); \
41095 + encode_8bit((uns8 **)ppData,pRrSubObj->u.Ipv4.Flags); \
41096 + zlog_info("RRO sub - IP: %x",pRrSubObj->u.Ipv4.IpAddr);\
41097 + PktLen += 6; \
41098 + VariableLengthObj += 6; \
41099 + break; \
41100 + case RRO_SUBTYPE_LABEL:\
41101 + encode_8bit((uns8 **)ppData,pRrSubObj->u.Label.Flags); \
41102 + encode_8bit((uns8 **)ppData,pRrSubObj->u.Label.CType); \
41103 + encode_32bit((uns8 **)ppData,pRrSubObj->u.Label.Label); \
41104 + zlog_info("RRO sub - Label: %x",pRrSubObj->u.Label.Label);\
41105 + PktLen += 6; \
41106 + VariableLengthObj += 6; \
41107 + break; \
41108 + default: \
41109 + zlog_err("the type %d of subobject is unknown %s %d",pRrSubObj->SubObjHdr.Type,__FILE__,__LINE__); \
41110 + return E_ERR;\
41111 + } \
41112 + pRrSubObj = pRrSubObj->next; \
41113 + } \
41114 + pRrSubObj = pRsvpPkt->AddedRro.rr; \
41115 + while(pRrSubObj != NULL) \
41116 + { \
41117 + encode_8bit((uns8 **)ppData,pRrSubObj->SubObjHdr.Type); \
41118 + encode_8bit((uns8 **)ppData,pRrSubObj->SubObjHdr.Length); \
41119 + PktLen += 2; \
41120 + VariableLengthObj += 2; \
41121 + if(pRrSubObj->SubObjHdr.Length != 8) \
41122 + { \
41123 + zlog_err(" the length of subobject is not 8!!!"); \
41124 + } \
41125 + switch(pRrSubObj->SubObjHdr.Type) \
41126 + { \
41127 + case RRO_SUBTYPE_IPV4: \
41128 + encode_32bit((uns8 **)ppData,pRrSubObj->u.Ipv4.IpAddr); \
41129 + encode_8bit((uns8 **)ppData,pRrSubObj->u.Ipv4.PrefixLen); \
41130 + encode_8bit((uns8 **)ppData,pRrSubObj->u.Ipv4.Flags); \
41131 + zlog_info(" RRO sub - IP: %x",pRrSubObj->u.Ipv4.IpAddr);\
41132 + PktLen += 6; \
41133 + VariableLengthObj += 6; \
41134 + break; \
41135 + case RRO_SUBTYPE_LABEL:\
41136 + encode_8bit((uns8 **)ppData,pRrSubObj->u.Label.Flags); \
41137 + encode_8bit((uns8 **)ppData,pRrSubObj->u.Label.CType); \
41138 + encode_32bit((uns8 **)ppData,pRrSubObj->u.Label.Label); \
41139 + zlog_info(" RRO sub - Label: %x",pRrSubObj->u.Label.Label);\
41140 + PktLen += 6; \
41141 + VariableLengthObj += 6; \
41142 + break; \
41143 + default: \
41144 + zlog_err("the type %d of subobject is unknown %s %d",pRrSubObj->SubObjHdr.Type,__FILE__,__LINE__); \
41145 + return E_ERR;\
41146 + } \
41147 + pRrSubObj = pRrSubObj->next; \
41148 + } \
41151 +#define ENCODE_ADSPEC \
41152 +{ \
41153 + encode_16bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.Resvd); \
41154 + encode_16bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.MsgLen); \
41155 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.PerServHdr.PerServHdr); \
41156 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.PerServHdr.BreakBitAndResvd); \
41157 + encode_16bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.PerServHdr.Length); \
41158 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param4Hdr.ParamID); \
41159 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param4Hdr.ParamFlags); \
41160 + encode_16bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param4Hdr.ParamLength); \
41161 + encode_32bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.IS_HopCount); \
41162 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param6Hdr.ParamID); \
41163 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param6Hdr.ParamFlags); \
41164 + encode_16bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param6Hdr.ParamLength); \
41165 + encode_float((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.PathBW); \
41166 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param8Hdr.ParamID); \
41167 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param8Hdr.ParamFlags); \
41168 + encode_16bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param8Hdr.ParamLength); \
41169 + encode_32bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.MinPathLatency); \
41170 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param10Hdr.ParamID); \
41171 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param10Hdr.ParamFlags); \
41172 + encode_16bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.Param10Hdr.ParamLength); \
41173 + encode_32bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.AdSpecGen.ComposedMTU); \
41174 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.PerServHdr.PerServHdr); \
41175 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.PerServHdr.BreakBitAndResvd); \
41176 + encode_16bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.PerServHdr.Length); \
41177 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param133Hdr.ParamID); \
41178 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param133Hdr.ParamFlags); \
41179 + encode_16bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param133Hdr.ParamLength); \
41180 + encode_32bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Ctot); \
41181 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param134Hdr.ParamID); \
41182 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param134Hdr.ParamFlags); \
41183 + encode_16bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param134Hdr.ParamLength); \
41184 + encode_32bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Dtot); \
41185 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param135Hdr.ParamID); \
41186 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param135Hdr.ParamFlags); \
41187 + encode_16bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param135Hdr.ParamLength); \
41188 + encode_32bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Csum); \
41189 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param136Hdr.ParamID); \
41190 + encode_8bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param136Hdr.ParamFlags); \
41191 + encode_16bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Param136Hdr.ParamLength); \
41192 + encode_32bit((uns8 **)ppData,pRsvpPkt->ReceivedAdSpec.GuarAdSpec.Dsum); \
41193 + PktLen += 76; \
41196 +#define ENCODE_ERR_SPEC \
41197 +{ \
41198 + encode_32bit((uns8 **)ppData,pRsvpPkt->ErrorSpec.IpAddr); \
41199 + encode_8bit((uns8 **)ppData,pRsvpPkt->ErrorSpec.Flags); \
41200 + encode_8bit((uns8 **)ppData,pRsvpPkt->ErrorSpec.ErrCode); \
41201 + encode_16bit((uns8 **)ppData,pRsvpPkt->ErrorSpec.ErrVal); \
41204 +#define ENCODE_FLOW_SPEC \
41205 +{ \
41206 + if(pFlowSpecObj->ServHdr.ServHdr == FLOW_SPEC_CTRL_LOAD_SERV_NUMBER) \
41207 + { \
41208 + ENCODE_OBJ_HDR(sizeof(MSG_HDR)+sizeof(SERV_HDR)+sizeof(PARAM_HDR)+sizeof(CTRL_LOAD_FLOW_SPEC)+sizeof(OBJ_HDR),\
41209 + FLOW_SPEC_CLASS,\
41210 + FLOW_SPEC_INTSERV_CTYPE)\
41211 + } \
41212 + else if(pFlowSpecObj->ServHdr.ServHdr == FLOW_SPEC_GUAR_SERV_NUMBER)\
41213 + { \
41214 + ENCODE_OBJ_HDR(sizeof(MSG_HDR)+sizeof(SERV_HDR)+sizeof(PARAM_HDR)+sizeof(GUAR_FLOW_SPEC)+sizeof(OBJ_HDR),\
41215 + FLOW_SPEC_CLASS,\
41216 + FLOW_SPEC_INTSERV_CTYPE) \
41217 + } \
41218 + else \
41219 + { \
41220 + zlog_err("FlowSpec of unknown type"); \
41221 + } \
41222 + encode_16bit((uns8 **)ppData,pFlowSpecObj->MsgHdr.VersionResvd); \
41223 + encode_16bit((uns8 **)ppData,pFlowSpecObj->MsgHdr.MessageLength); \
41224 + encode_8bit((uns8 **)ppData,pFlowSpecObj->ServHdr.ServHdr); \
41225 + encode_8bit((uns8 **)ppData,pFlowSpecObj->ServHdr.Resvd); \
41226 + encode_16bit((uns8 **)ppData,pFlowSpecObj->ServHdr.ServLength); \
41227 + encode_8bit((uns8 **)ppData,pFlowSpecObj->ParamHdr.ParamID); \
41228 + encode_8bit((uns8 **)ppData,pFlowSpecObj->ParamHdr.ParamFlags); \
41229 + encode_16bit((uns8 **)ppData,pFlowSpecObj->ParamHdr.ParamLength); \
41230 + PktLen += 12; \
41231 + if(pFlowSpecObj->ServHdr.ServHdr == FLOW_SPEC_CTRL_LOAD_SERV_NUMBER) \
41232 + { \
41233 + encode_float((uns8 **)ppData,pFlowSpecObj->u.CtrlLoad.TockenBucketRate);\
41234 + encode_float((uns8 **)ppData,pFlowSpecObj->u.CtrlLoad.TockenBucketSize);\
41235 + encode_float((uns8 **)ppData,pFlowSpecObj->u.CtrlLoad.PeakDataRate);\
41236 + encode_float((uns8 **)ppData,pFlowSpecObj->u.CtrlLoad.MinPolicedUnit);\
41237 + encode_float((uns8 **)ppData,pFlowSpecObj->u.CtrlLoad.MaxPacketSize);\
41238 + PktLen += 20;\
41239 + }\
41240 + else if(pFlowSpecObj->ServHdr.ServHdr == FLOW_SPEC_GUAR_SERV_NUMBER)\
41241 + {\
41242 + encode_float((uns8 **)ppData,pFlowSpecObj->u.Guar.CtrlLoad.TockenBucketRate);\
41243 + encode_float((uns8 **)ppData,pFlowSpecObj->u.Guar.CtrlLoad.TockenBucketSize);\
41244 + encode_float((uns8 **)ppData,pFlowSpecObj->u.Guar.CtrlLoad.PeakDataRate);\
41245 + encode_float((uns8 **)ppData,pFlowSpecObj->u.Guar.CtrlLoad.MinPolicedUnit);\
41246 + encode_float((uns8 **)ppData,pFlowSpecObj->u.Guar.CtrlLoad.MaxPacketSize);\
41247 + encode_8bit((uns8 **)ppData,pFlowSpecObj->u.Guar.GuarSpecificParamHdr.ParamID);\
41248 + encode_8bit((uns8 **)ppData,pFlowSpecObj->u.Guar.GuarSpecificParamHdr.ParamFlags);\
41249 + encode_16bit((uns8 **)ppData,pFlowSpecObj->u.Guar.GuarSpecificParamHdr.ParamLength);\
41250 + encode_float((uns8 **)ppData,pFlowSpecObj->u.Guar.Rate);\
41251 + encode_32bit((uns8 **)ppData,pFlowSpecObj->u.Guar.SlackTerm);\
41252 + PktLen += 32;\
41253 + }\
41256 +#define ENCODE_FILTER_SPEC \
41258 + pFilterSpecData = pFilterList->pFilterSpecData;\
41259 + ENCODE_OBJ_HDR(sizeof(FILTER_SPEC_OBJ)+sizeof(OBJ_HDR),FILTER_SPEC_CLASS,FILTER_SPEC_LSP_IPV4_CTYPE)\
41260 + encode_32bit((uns8 **)ppData,pFilterSpecData->FilterSpec.IpAddr);\
41261 + encode_16bit((uns8 **)ppData,pFilterSpecData->FilterSpec.Resvd);\
41262 + encode_16bit((uns8 **)ppData,pFilterSpecData->FilterSpec.LspId);\
41263 + zlog_info("encoding FILTER_SPEC %x %x",pFilterSpecData->FilterSpec.IpAddr,pFilterSpecData->FilterSpec.LspId);\
41264 + PktLen += 8;\
41265 + ENCODE_OBJ_HDR(sizeof(LABEL_OBJ)+sizeof(OBJ_HDR),LABEL_CLASS,COMMON_CTYPE)\
41266 + encode_32bit((uns8 **)ppData,pFilterSpecData->SentLabel.Label);\
41267 + PktLen += 4;\
41268 + pRsvpPkt->ReceivedRro.rr = pFilterSpecData->Rro.rr;\
41269 + if((pRsvpPkt->ReceivedRro.rr != NULL)||\
41270 + (pRsvpPkt->AddedRro.rr != NULL))\
41271 + {\
41272 + ENCODE_OBJ_HDR(0,RECORDED_ROUTE_CLASS,COMMON_CTYPE)\
41273 + ENCODE_RRO\
41274 + encode_16bit((uns8 **)&pVariableLengthObj,(uns32)VariableLengthObj);\
41275 + }\
41276 + pRsvpPkt->ReceivedRro.rr = NULL;\
41280 +E_RC
41281 +EncodeAndSendRsvpPathMessage (RSVP_PKT * pRsvpPkt,
41282 + IPV4_ADDR DestIpAddr,
41283 + uns32 OutIf,
41284 + uns8 ttl,
41285 + char **ppSentBuffer, uns16 * pSentBufferLen)
41287 + uns16 PktLen = 0;
41288 + uns8 VersionFlags = RSVP_VERSION;
41289 + uns16 *pCheckSum, CheckSum = 0;
41290 + uns16 *pRsvpLength;
41291 + uns8 *pData = BigBuffer;
41292 + uns8 **ppData = &pData;
41293 + uns16 *pVariableLengthObj;
41294 + uns16 VariableLengthObj;
41295 + zlog_info ("entering EncodeAndSendRsvpPathMessage");
41296 + memset (BigBuffer, 0, 1500);
41298 + ENCODE_COMMON_HDR (VersionFlags, PATH_MSG, 0 /* CheckSum */ , ttl,
41299 + 0 /* resvd */ , 0 /* RsvpLength */ )
41300 + ENCODE_OBJ_HDR (sizeof (SESSION_OBJ) + sizeof (OBJ_HDR), SESSION_CLASS,
41301 + SESSION_CTYPE) ENCODE_SESSION
41302 + ENCODE_OBJ_HDR (sizeof (RSVP_HOP_OBJ) + sizeof (OBJ_HDR), RSVP_HOP_CLASS,
41303 + COMMON_CTYPE) ENCODE_RSVP_HOP
41304 + ENCODE_OBJ_HDR (sizeof (TIME_VALUES_OBJ) + sizeof (OBJ_HDR),
41305 + TIME_VALUES_CLASS,
41306 + COMMON_CTYPE) ENCODE_TIME_VALUES if ((pRsvpPkt->
41307 + ReceivedEro.er !=
41308 + NULL)
41309 + || (pRsvpPkt->
41310 + SentEro.er !=
41311 + NULL))
41313 + ENCODE_OBJ_HDR (0, EXPLICIT_ROUTE_CLASS, COMMON_CTYPE)
41314 + ENCODE_ERO
41315 + encode_16bit ((uns8 **) & pVariableLengthObj,
41316 + (uns32) VariableLengthObj);
41318 + ENCODE_OBJ_HDR (sizeof (LABEL_REQUEST_OBJ) + sizeof (OBJ_HDR),
41319 + LABEL_REQUEST_CLASS,
41320 + COMMON_CTYPE) ENCODE_LABEL_REQUEST if (pRsvpPkt->
41321 + SessionAttributes.
41322 + CType ==
41323 + SESSION_ATTRIBUTES_RA_CLASS_TYPE)
41325 + ENCODE_OBJ_HDR (0, SESSION_ATTRIBUTE_CLASS,
41326 + pRsvpPkt->SessionAttributes.
41327 + CType) ENCODE_SESSION_ATTRIBUTES encode_16bit ((uns8 **)
41329 + pVariableLengthObj,
41330 + (uns32)
41331 + VariableLengthObj);
41333 + else if (pRsvpPkt->SessionAttributes.CType == SESSION_ATTRIBUTES_CLASS_TYPE)
41335 + ENCODE_OBJ_HDR (0, SESSION_ATTRIBUTE_CLASS,
41336 + pRsvpPkt->SessionAttributes.
41337 + CType) ENCODE_SESSION_ATTRIBUTES encode_16bit ((uns8 **)
41339 + pVariableLengthObj,
41340 + (uns32)
41341 + VariableLengthObj);
41343 + ENCODE_OBJ_HDR (sizeof (SENDER_TEMPLATE_OBJ) + sizeof (OBJ_HDR),
41344 + SENDER_TEMPLATE_CLASS,
41345 + SENDER_TEMPLATE_CTYPE) ENCODE_SENDER_TEMPLATE
41346 + ENCODE_OBJ_HDR (sizeof (SENDER_TSPEC_OBJ) + sizeof (OBJ_HDR),
41347 + SENDER_TSPEC_CLASS,
41348 + SENDER_TSPEC_CTYPE) ENCODE_SENDER_TSPEC if (pRsvpPkt->
41349 + SentAdSpec.
41350 + CType != 0)
41352 + ENCODE_OBJ_HDR (sizeof (ADSPEC_OBJ) + sizeof (OBJ_HDR), ADSPEC_CLASS,
41353 + COMMON_CTYPE) ENCODE_ADSPEC}
41354 + if ((pRsvpPkt->ReceivedRro.rr != NULL) || (pRsvpPkt->AddedRro.rr != NULL))
41356 + ENCODE_OBJ_HDR (0, RECORDED_ROUTE_CLASS, COMMON_CTYPE)
41357 + ENCODE_RRO
41358 + encode_16bit ((uns8 **) & pVariableLengthObj,
41359 + (uns32) VariableLengthObj);
41361 + encode_16bit ((uns8 **) & pRsvpLength, PktLen);
41362 + rsvp_calc_pkt_cksum (BigBuffer, PktLen, &CheckSum);
41363 + encode_16bit ((uns8 **) & pCheckSum, CheckSum);
41364 + if (((*ppSentBuffer) = (char *) XMALLOC (MTYPE_RSVP, PktLen)) == NULL)
41366 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
41368 + else
41370 + *pSentBufferLen = PktLen;
41371 + memcpy ((*ppSentBuffer), BigBuffer, *pSentBufferLen);
41373 + return SendRawData (BigBuffer, PktLen, DestIpAddr, OutIf, ttl, TRUE);
41376 +E_RC
41377 +EncodeAndSendRsvpResvMessage (RSVP_PKT * pRsvpPkt,
41378 + IPV4_ADDR DestIpAddr,
41379 + uns32 OutIf,
41380 + uns8 ttl,
41381 + char **ppSentBuffer, uns16 * pSentBufferLen)
41383 + uns16 PktLen = 0;
41384 + uns8 VersionFlags = RSVP_VERSION;
41385 + uns16 *pCheckSum, CheckSum = 0;
41386 + uns16 *pRsvpLength;
41387 + uns8 *pData = BigBuffer;
41388 + uns8 **ppData = &pData;
41389 + uns16 *pVariableLengthObj;
41390 + uns16 VariableLengthObj;
41391 + FILTER_LIST *pFilterList;
41392 + FILTER_SPEC_DATA *pFilterSpecData;
41393 + FLOW_SPEC_OBJ *pFlowSpecObj;
41395 + zlog_info ("entering EncodeAndSendRsvpResvMessage");
41396 + memset (BigBuffer, 0, 1500);
41398 + ENCODE_COMMON_HDR (VersionFlags, RESV_MSG, 0 /* CheckSum */ , ttl,
41399 + 0 /* resvd */ , 0 /* RsvpLength */ )
41400 + ENCODE_OBJ_HDR (sizeof (SESSION_OBJ) + sizeof (OBJ_HDR), SESSION_CLASS,
41401 + SESSION_CTYPE) ENCODE_SESSION
41402 + ENCODE_OBJ_HDR (sizeof (RSVP_HOP_OBJ) + sizeof (OBJ_HDR), RSVP_HOP_CLASS,
41403 + COMMON_CTYPE) ENCODE_RSVP_HOP
41404 + ENCODE_OBJ_HDR (sizeof (TIME_VALUES_OBJ) + sizeof (OBJ_HDR),
41405 + TIME_VALUES_CLASS,
41406 + COMMON_CTYPE) ENCODE_TIME_VALUES
41407 + ENCODE_OBJ_HDR (sizeof (STYLE_OBJ) + sizeof (OBJ_HDR), STYLE_CLASS,
41408 + COMMON_CTYPE) ENCODE_STYLE pFilterList =
41409 + pRsvpPkt->pFilterList;
41410 + if (pRsvpPkt->Style.OptionVector2 == SE_STYLE_BITS)
41412 + if ((pFilterList == NULL) || (pFilterList->pFilterSpecData == NULL))
41414 + zlog_err ("an error at %s %d", __FILE__, __LINE__);
41415 + return E_ERR;
41417 + pFilterSpecData = pFilterList->pFilterSpecData;
41418 + pFlowSpecObj = &pFilterSpecData->pPHopResvRefreshList->FwdFlowSpec;
41419 + ENCODE_FLOW_SPEC while (pFilterList != NULL)
41421 + pFilterSpecData = pFilterList->pFilterSpecData;
41422 + ENCODE_FILTER_SPEC pFilterList = pFilterList->next;
41425 + else
41427 + while (pFilterList != NULL)
41429 + pFilterSpecData = pFilterList->pFilterSpecData;
41430 + pFlowSpecObj = &pFilterSpecData->FlowSpec;
41431 + ENCODE_FLOW_SPEC ENCODE_FILTER_SPEC pFilterList = pFilterList->next;
41434 +#if 0
41435 + pRsvpPkt->AddedRro.rr = NULL;
41436 +#endif
41438 + encode_16bit ((uns8 **) & pRsvpLength, PktLen);
41439 + rsvp_calc_pkt_cksum (BigBuffer, PktLen, &CheckSum);
41440 + encode_16bit ((uns8 **) & pCheckSum, CheckSum);
41441 + if (((*ppSentBuffer) = (char *) XMALLOC (MTYPE_RSVP, PktLen)) == NULL)
41443 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
41445 + else
41447 + *pSentBufferLen = PktLen;
41448 + memcpy ((*ppSentBuffer), BigBuffer, *pSentBufferLen);
41450 + return SendRawData (BigBuffer, PktLen, DestIpAddr, OutIf, ttl, FALSE);
41453 +E_RC
41454 +EncodeAndSendRsvpPathErrMessage (RSVP_PKT * pRsvpPkt, IPV4_ADDR DestIpAddr,
41455 + uns32 OutIf, uns8 ttl)
41457 + uns16 PktLen = 0;
41458 + uns8 VersionFlags = RSVP_VERSION;
41459 + uns16 *pCheckSum, CheckSum = 0;
41460 + uns16 *pRsvpLength;
41461 + uns8 *pData = BigBuffer;
41462 + uns8 **ppData = &pData;
41463 + uns16 *pVariableLengthObj;
41465 + zlog_info ("entering EncodeAndSendRsvpPathErrMessage");
41466 + memset (BigBuffer, 0, 1500);
41468 + ENCODE_COMMON_HDR (VersionFlags, PATH_ERR_MSG, 0 /* CheckSum */ , ttl,
41469 + 0 /* resvd */ , 0 /* RsvpLength */ )
41470 + ENCODE_OBJ_HDR (sizeof (SESSION_OBJ) + sizeof (OBJ_HDR), SESSION_CLASS,
41471 + SESSION_CTYPE) ENCODE_SESSION
41472 + ENCODE_OBJ_HDR (sizeof (ERR_SPEC_OBJ) + sizeof (OBJ_HDR), ERR_SPEC_CLASS,
41473 + COMMON_CTYPE) ENCODE_ERR_SPEC
41474 + ENCODE_OBJ_HDR (sizeof (SENDER_TEMPLATE_OBJ) + sizeof (OBJ_HDR),
41475 + SENDER_TEMPLATE_CLASS,
41476 + SENDER_TEMPLATE_CTYPE) ENCODE_SENDER_TEMPLATE
41477 + ENCODE_OBJ_HDR (sizeof (SENDER_TSPEC_OBJ) + sizeof (OBJ_HDR),
41478 + SENDER_TSPEC_CLASS,
41479 + SENDER_TSPEC_CTYPE) ENCODE_SENDER_TSPEC if (pRsvpPkt->
41480 + SentAdSpec.
41481 + CType != 0)
41483 + ENCODE_OBJ_HDR (sizeof (ADSPEC_OBJ) + sizeof (OBJ_HDR), ADSPEC_CLASS,
41484 + COMMON_CTYPE) ENCODE_ADSPEC}
41485 + encode_16bit ((uns8 **) & pRsvpLength, PktLen);
41486 + rsvp_calc_pkt_cksum (BigBuffer, PktLen, &CheckSum);
41487 + encode_16bit ((uns8 **) & pCheckSum, CheckSum);
41488 + return SendRawData (BigBuffer, PktLen, DestIpAddr, OutIf, ttl, TRUE);
41491 +E_RC
41492 +EncodeAndSendRsvpPathTearMessage (RSVP_PKT * pRsvpPkt, IPV4_ADDR DestIpAddr,
41493 + uns32 OutIf, uns8 ttl)
41495 + uns16 PktLen = 0;
41496 + uns8 VersionFlags = RSVP_VERSION;
41497 + uns16 *pCheckSum, CheckSum = 0;
41498 + uns16 *pRsvpLength;
41499 + uns8 *pData = BigBuffer;
41500 + uns8 **ppData = &pData;
41501 + uns16 *pVariableLengthObj;
41503 + zlog_info ("entering EncodeAndSendRsvpPathTearMessage");
41504 + memset (BigBuffer, 0, 1500);
41506 + ENCODE_COMMON_HDR (VersionFlags, PATH_TEAR_MSG, 0 /* CheckSum */ , ttl,
41507 + 0 /* resvd */ , 0 /* RsvpLength */ )
41508 + ENCODE_OBJ_HDR (sizeof (SESSION_OBJ) + sizeof (OBJ_HDR), SESSION_CLASS,
41509 + SESSION_CTYPE) ENCODE_SESSION
41510 + ENCODE_OBJ_HDR (sizeof (RSVP_HOP_OBJ) + sizeof (OBJ_HDR), RSVP_HOP_CLASS,
41511 + COMMON_CTYPE) ENCODE_RSVP_HOP
41512 + ENCODE_OBJ_HDR (sizeof (SENDER_TEMPLATE_OBJ) + sizeof (OBJ_HDR),
41513 + SENDER_TEMPLATE_CLASS,
41514 + SENDER_TEMPLATE_CTYPE) ENCODE_SENDER_TEMPLATE
41515 + ENCODE_OBJ_HDR (sizeof (SENDER_TSPEC_OBJ) + sizeof (OBJ_HDR),
41516 + SENDER_TSPEC_CLASS,
41517 + SENDER_TSPEC_CTYPE) ENCODE_SENDER_TSPEC if (pRsvpPkt->
41518 + SentAdSpec.
41519 + CType != 0)
41521 + ENCODE_OBJ_HDR (sizeof (ADSPEC_OBJ) + sizeof (OBJ_HDR), ADSPEC_CLASS,
41522 + COMMON_CTYPE) ENCODE_ADSPEC}
41523 + encode_16bit ((uns8 **) & pRsvpLength, PktLen);
41524 + rsvp_calc_pkt_cksum (BigBuffer, PktLen, &CheckSum);
41525 + encode_16bit ((uns8 **) & pCheckSum, CheckSum);
41526 + return SendRawData (BigBuffer, PktLen, DestIpAddr, OutIf, ttl, TRUE);
41529 +E_RC
41530 +EncodeAndSendRsvpResvErrMessage (RSVP_PKT * pRsvpPkt, IPV4_ADDR DestIpAddr,
41531 + uns32 OutIf, uns8 ttl)
41533 + uns16 PktLen = 0;
41534 + uns8 VersionFlags = RSVP_VERSION;
41535 + uns16 *pCheckSum, CheckSum = 0;
41536 + uns16 *pRsvpLength;
41537 + uns8 *pData = BigBuffer;
41538 + uns8 **ppData = &pData;
41539 + uns16 *pVariableLengthObj;
41540 + uns16 VariableLengthObj;
41541 + FILTER_LIST *pFilterList;
41542 + FILTER_SPEC_DATA *pFilterSpecData;
41543 + FLOW_SPEC_OBJ *pFlowSpecObj;
41545 + zlog_info ("entering EncodeAndSendRsvpResvErrMessage");
41546 + memset (BigBuffer, 0, 1500);
41548 + ENCODE_COMMON_HDR (VersionFlags, RESV_ERR_MSG, 0 /* CheckSum */ , ttl,
41549 + 0 /* resvd */ , 0 /* RsvpLength */ )
41550 + ENCODE_OBJ_HDR (sizeof (SESSION_OBJ) + sizeof (OBJ_HDR), SESSION_CLASS,
41551 + SESSION_CTYPE) ENCODE_SESSION
41552 + ENCODE_OBJ_HDR (sizeof (RSVP_HOP_OBJ) + sizeof (OBJ_HDR), RSVP_HOP_CLASS,
41553 + COMMON_CTYPE) ENCODE_RSVP_HOP
41554 + ENCODE_OBJ_HDR (sizeof (ERR_SPEC_OBJ) + sizeof (OBJ_HDR), ERR_SPEC_CLASS,
41555 + COMMON_CTYPE) ENCODE_ERR_SPEC
41556 + ENCODE_OBJ_HDR (sizeof (STYLE_OBJ) + sizeof (OBJ_HDR), STYLE_CLASS,
41557 + COMMON_CTYPE) ENCODE_STYLE pFilterList =
41558 + pRsvpPkt->pFilterList;
41559 + if (pRsvpPkt->Style.OptionVector2 == SE_STYLE_BITS)
41561 + if ((pFilterList == NULL) || (pFilterList->pFilterSpecData == NULL))
41563 + zlog_err ("an error at %s %d", __FILE__, __LINE__);
41564 + return E_ERR;
41566 + pFilterSpecData = pFilterList->pFilterSpecData;
41567 + pFlowSpecObj =
41568 + (pFilterSpecData->NewFlowSpecValid) ? &pFilterSpecData->
41569 + NewFlowSpec : &pFilterSpecData->FlowSpec;
41570 + ENCODE_FLOW_SPEC while (pFilterList != NULL)
41572 + pFilterSpecData = pFilterList->pFilterSpecData;
41573 + ENCODE_FILTER_SPEC pFilterList = pFilterList->next;
41576 + else
41578 + while (pFilterList != NULL)
41580 + pFilterSpecData = pFilterList->pFilterSpecData;
41581 + pFlowSpecObj = &pFilterSpecData->FlowSpec;
41582 + ENCODE_FLOW_SPEC ENCODE_FILTER_SPEC pFilterList = pFilterList->next;
41585 + pRsvpPkt->AddedRro.rr = NULL;
41587 + encode_16bit ((uns8 **) & pRsvpLength, PktLen);
41588 + rsvp_calc_pkt_cksum (BigBuffer, PktLen, &CheckSum);
41589 + encode_16bit ((uns8 **) & pCheckSum, CheckSum);
41590 + return SendRawData (BigBuffer, PktLen, DestIpAddr, OutIf, ttl, TRUE);
41593 +E_RC
41594 +EncodeAndSendRsvpResvTearMessage (RSVP_PKT * pRsvpPkt, IPV4_ADDR DestIpAddr,
41595 + uns32 OutIf, uns8 ttl)
41597 + uns16 PktLen = 0;
41598 + uns8 VersionFlags = RSVP_VERSION;
41599 + uns16 *pCheckSum, CheckSum = 0;
41600 + uns16 *pRsvpLength;
41601 + uns8 *pData = BigBuffer;
41602 + uns8 **ppData = &pData;
41603 + uns16 *pVariableLengthObj;
41604 + uns16 VariableLengthObj;
41605 + FILTER_LIST *pFilterList;
41606 + FILTER_SPEC_DATA *pFilterSpecData;
41607 + FLOW_SPEC_OBJ *pFlowSpecObj;
41609 + zlog_info ("entering EncodeAndSendRsvpResvTearMessage");
41610 + memset (BigBuffer, 0, 1500);
41612 + ENCODE_COMMON_HDR (VersionFlags, RESV_TEAR_MSG, 0 /* CheckSum */ , ttl,
41613 + 0 /* resvd */ , 0 /* RsvpLength */ )
41614 + ENCODE_OBJ_HDR (sizeof (SESSION_OBJ) + sizeof (OBJ_HDR), SESSION_CLASS,
41615 + SESSION_CTYPE) ENCODE_SESSION
41616 + ENCODE_OBJ_HDR (sizeof (RSVP_HOP_OBJ) + sizeof (OBJ_HDR), RSVP_HOP_CLASS,
41617 + COMMON_CTYPE) ENCODE_RSVP_HOP
41618 + ENCODE_OBJ_HDR (sizeof (STYLE_OBJ) + sizeof (OBJ_HDR), STYLE_CLASS,
41619 + COMMON_CTYPE) ENCODE_STYLE pFilterList =
41620 + pRsvpPkt->pFilterList;
41621 + if (pRsvpPkt->Style.OptionVector2 == SE_STYLE_BITS)
41623 + if ((pFilterList == NULL) || (pFilterList->pFilterSpecData == NULL))
41625 + zlog_err ("an error at %s %d", __FILE__, __LINE__);
41626 + return E_ERR;
41628 + pFilterSpecData = pFilterList->pFilterSpecData;
41629 + pFlowSpecObj = &pFilterSpecData->pPHopResvRefreshList->FwdFlowSpec;
41630 + ENCODE_FLOW_SPEC while (pFilterList != NULL)
41632 + pFilterSpecData = pFilterList->pFilterSpecData;
41633 + ENCODE_FILTER_SPEC pFilterList = pFilterList->next;
41636 + else
41638 + while (pFilterList != NULL)
41640 + pFilterSpecData = pFilterList->pFilterSpecData;
41641 + pFlowSpecObj = &pFilterSpecData->FlowSpec;
41642 + ENCODE_FLOW_SPEC ENCODE_FILTER_SPEC pFilterList = pFilterList->next;
41645 + pRsvpPkt->AddedRro.rr = NULL;
41647 + encode_16bit ((uns8 **) & pRsvpLength, PktLen);
41648 + rsvp_calc_pkt_cksum (BigBuffer, PktLen, &CheckSum);
41649 + encode_16bit ((uns8 **) & pCheckSum, CheckSum);
41650 + return SendRawData (BigBuffer, PktLen, DestIpAddr, OutIf, ttl, TRUE);
41652 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_encode.h quagga-mpls/rsvpd/rsvp_encode.h
41653 --- quagga/rsvpd/rsvp_encode.h 1969-12-31 18:00:00.000000000 -0600
41654 +++ quagga-mpls/rsvpd/rsvp_encode.h 2007-06-14 21:35:58.000000000 -0500
41655 @@ -0,0 +1,35 @@
41656 +#ifndef __RSVP_ENCODE_H_
41657 +#define __RSVP_ENCODE_H_
41659 +E_RC EncodeAndSendRsvpPathTearMessage (RSVP_PKT * pRsvpPkt,
41660 + IPV4_ADDR DestIpAddr,
41661 + uns32 OutIf, uns8 ttl);
41662 +E_RC EncodeAndSendRsvpPathErrMessage (RSVP_PKT * pRsvpPkt,
41663 + IPV4_ADDR DestIpAddr,
41664 + uns32 OutIf, uns8 ttl);
41666 +E_RC EncodeAndSendRsvpPathMessage (RSVP_PKT * pRsvpPkt,
41667 + IPV4_ADDR DestIpAddr,
41668 + uns32 OutIf,
41669 + uns8 ttl,
41670 + char **ppSentBuffer,
41671 + uns16 * pSentBufferLen);
41673 +E_RC EncodeAndSendRsvpResvErrMessage (RSVP_PKT * pRsvpPkt,
41674 + IPV4_ADDR DestIpAddr,
41675 + uns32 OutIf, uns8 ttl);
41677 +E_RC EncodeAndSendRsvpResvMessage (RSVP_PKT * pRsvpPkt,
41678 + IPV4_ADDR DestIpAddr,
41679 + uns32 OutIf,
41680 + uns8 ttl,
41681 + char **ppSentBuffer,
41682 + uns16 * pSentBufferLen);
41684 +E_RC EncodeAndSendRsvpResvTearMessage (RSVP_PKT * pRsvpPkt,
41685 + IPV4_ADDR DestIpAddr,
41686 + uns32 OutIf, uns8 ttl);
41688 +void rsvp_calc_pkt_cksum (char *u, unsigned int PktLen, uns16 * const pCksum);
41690 +#endif
41691 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp.h quagga-mpls/rsvpd/rsvp.h
41692 --- quagga/rsvpd/rsvp.h 1969-12-31 18:00:00.000000000 -0600
41693 +++ quagga-mpls/rsvpd/rsvp.h 2007-07-03 00:41:19.000000000 -0500
41694 @@ -0,0 +1,46 @@
41695 +#ifndef __RSVP_INCLUDES__
41696 +#define __RSVP_INCLUDES__
41698 +#include<stdio.h>
41699 +#include<stdlib.h>
41700 +#include<string.h>
41701 +#include <sys/types.h>
41702 +#include <sys/socket.h>
41703 +#include <sys/ioctl.h>
41704 +#include <net/if.h>
41705 +#include <netinet/in.h>
41706 +#include <netinet/ip.h>
41707 +#include <unistd.h>
41708 +#include <time.h>
41709 +#include <sys/time.h>
41710 +#include <sys/file.h>
41711 +#include <sys/fcntl.h>
41712 +#include <sys/ioctl.h>
41713 +#include <sys/uio.h>
41714 +#include <ctype.h>
41715 +#include<math.h>
41716 +#include<errno.h>
41717 +#include <zebra.h>
41718 +#include "thread.h"
41719 +#include "vty.h"
41720 +#include "command.h"
41721 +#include "log.h"
41722 +#include "memory.h"
41723 +#include "patricia.h"
41725 +#include "general.h"
41726 +#include "messages.h"
41727 +#include "rsvp_packet.h"
41728 +#include "te_lib.h"
41729 +#include "rsvp_psb.h"
41730 +#include "rsvp_rsb.h"
41731 +#include "rsvp_socket.h"
41732 +#include "rsvp_utilities.h"
41733 +#include "rsvp_decode.h"
41734 +#include "rsvp_encode.h"
41735 +#include "rsvp_api.h"
41737 +#define RSVP_VTY_PORT 2699
41738 +#define RSVP_DEFAULT_CONFIG "rsvpd.conf"
41740 +#endif
41741 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_main.c quagga-mpls/rsvpd/rsvp_main.c
41742 --- quagga/rsvpd/rsvp_main.c 1969-12-31 18:00:00.000000000 -0600
41743 +++ quagga-mpls/rsvpd/rsvp_main.c 2007-07-02 23:40:48.000000000 -0500
41744 @@ -0,0 +1,276 @@
41745 +/* Module: rsvp_main.c
41746 + Contains: RSVP entry point
41747 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
41748 + */
41750 +#include <zebra.h>
41751 +#include <lib/version.h>
41752 +#include "getopt.h"
41753 +#include "thread.h"
41754 +#include "vty.h"
41755 +#include "log.h"
41756 +#include "sigevent.h"
41757 +#include "privs.h"
41758 +#include "memory.h"
41760 +#include "rsvp.h"
41761 +#include "rsvp_vty.h"
41762 +#include "rsvp_zebra.h"
41763 +#include "rsvp_packet.h"
41765 +/* rsvpd privileges */
41766 +zebra_capabilities_t _caps_p[] = {
41767 + ZCAP_NET_RAW,
41768 + ZCAP_BIND,
41769 + ZCAP_NET_ADMIN,
41772 +struct zebra_privs_t rsvpd_privs = {
41773 +#if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
41774 + .user = QUAGGA_USER,
41775 + .group = QUAGGA_GROUP,
41776 +#endif
41777 +#if defined(VTY_GROUP)
41778 + .vty_group = VTY_GROUP,
41779 +#endif
41780 + .caps_p = _caps_p,
41781 + .cap_num_p = sizeof (_caps_p) / sizeof (_caps_p[0]),
41782 + .cap_num_i = 0
41785 +/* Configuration filename and directory. */
41786 +char config_default[] = SYSCONFDIR RSVP_DEFAULT_CONFIG;
41788 +/* RSVPd options. */
41789 +struct option longopts[] = {
41790 + {"daemon", no_argument, NULL, 'd'},
41791 + {"config_file", required_argument, NULL, 'f'},
41792 + {"pid_file", required_argument, NULL, 'i'},
41793 + {"log_mode", no_argument, NULL, 'l'},
41794 + {"dryrun", no_argument, NULL, 'C'},
41795 + {"help", no_argument, NULL, 'h'},
41796 + {"vty_addr", required_argument, NULL, 'A'},
41797 + {"vty_port", required_argument, NULL, 'P'},
41798 + {"user", required_argument, NULL, 'u'},
41799 + {"group", required_argument, NULL, 'g'},
41800 + {"version", no_argument, NULL, 'v'},
41801 + {0}
41804 +struct thread_master *master;
41806 +/* Process ID saved for use by init system */
41807 +const char *pid_file = PATH_RSVPD_PID;
41809 +/* Help information display. */
41810 +static void __attribute__ ((noreturn)) usage (char *progname, int status)
41812 + if (status != 0)
41813 + fprintf (stderr, "Try `%s --help' for more information.\n", progname);
41814 + else
41816 + printf ("Usage : %s [OPTION...]\n\
41817 +Daemon which manages RSVP.\n\n\
41818 +-d, --daemon Runs in daemon mode\n\
41819 +-f, --config_file Set configuration file name\n\
41820 +-i, --pid_file Set process identifier file name\n\
41821 +-A, --vty_addr Set vty's bind address\n\
41822 +-P, --vty_port Set vty's port number\n\
41823 +-u, --user User to run as\n\
41824 +-g, --group Group to run as\n\
41825 +-v, --version Print program version\n\
41826 +-C, --dryrun Check configuration for validity and exit\n\
41827 +-h, --help Display this help and exit\n\
41828 +\n\
41829 +Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
41831 + exit (status);
41834 +/* SIGHUP handler. */
41835 +static void
41836 +sighup (void)
41838 + zlog (NULL, LOG_INFO, "SIGHUP received");
41841 +/* SIGINT / SIGTERM handler. */
41842 +static void
41843 +sigint (void)
41845 + zlog_notice ("Terminating on signal");
41848 +/* SIGUSR1 handler. */
41849 +static void
41850 +sigusr1 (void)
41852 + zlog_rotate (NULL);
41855 +struct quagga_signal_t rsvp_signals[] = {
41857 + .signal = SIGHUP,
41858 + .handler = &sighup,
41859 + },
41861 + .signal = SIGUSR1,
41862 + .handler = &sigusr1,
41863 + },
41865 + .signal = SIGINT,
41866 + .handler = &sigint,
41867 + },
41869 + .signal = SIGTERM,
41870 + .handler = &sigint,
41871 + },
41874 +/* RSVPd main routine. */
41875 +int
41876 +main (int argc, char **argv)
41878 + char *p;
41879 + char *vty_addr = NULL;
41880 + int vty_port = RSVP_VTY_PORT;
41881 + int daemon_mode = 0;
41882 + char *config_file = NULL;
41883 + char *progname;
41884 + struct thread thread;
41885 + int dryrun = 0;
41887 + /* Set umask before anything for security */
41888 + umask (0027);
41890 + /* get program name */
41891 + progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
41893 + /* Invoked by a priviledged user? -- endo. */
41894 + if (geteuid () != 0)
41896 + errno = EPERM;
41897 + perror (progname);
41898 + exit (1);
41901 + zlog_default = openzlog (progname, ZLOG_RSVP,
41902 + LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
41904 + while (1)
41906 + int opt;
41908 + opt = getopt_long (argc, argv, "dlf:i:hA:P:u:g:vC", longopts, 0);
41910 + if (opt == EOF)
41911 + break;
41913 + switch (opt)
41915 + case 0:
41916 + break;
41917 + case 'd':
41918 + daemon_mode = 1;
41919 + break;
41920 + case 'f':
41921 + config_file = optarg;
41922 + break;
41923 + case 'A':
41924 + vty_addr = optarg;
41925 + break;
41926 + case 'i':
41927 + pid_file = optarg;
41928 + break;
41929 + case 'P':
41930 + /* Deal with atoi() returning 0 on failure, and rsvpd not
41931 + listening on rsvpd port... */
41932 + if (strcmp (optarg, "0") == 0)
41934 + vty_port = 0;
41935 + break;
41937 + vty_port = atoi (optarg);
41938 + vty_port = (vty_port ? vty_port : RSVP_VTY_PORT);
41939 + break;
41940 + case 'u':
41941 + rsvpd_privs.user = optarg;
41942 + break;
41943 + case 'g':
41944 + rsvpd_privs.group = optarg;
41945 + break;
41946 + case 'v':
41947 + print_version (progname);
41948 + exit (0);
41949 + break;
41950 + case 'C':
41951 + dryrun = 1;
41952 + break;
41953 + case 'h':
41954 + usage (progname, 0);
41955 + break;
41956 + default:
41957 + usage (progname, 1);
41958 + break;
41962 + /* Make master thread emulator. */
41963 + master = thread_master_create ();
41965 + /* Library inits. */
41966 + zprivs_init (&rsvpd_privs);
41967 + signal_init (master, Q_SIGC (rsvp_signals), rsvp_signals);
41968 + cmd_init (1);
41969 + vty_init (master);
41970 + memory_init ();
41971 + rsvp_vty ();
41973 + InitRsvpDecoder ();
41974 + InitRsvpPathMessageProcessing ();
41975 + InitResvProcessing ();
41976 + InitInterfaceIpAdressesDB ();
41978 + if (rdb_create () != E_OK)
41980 + zlog_err ("an error on RDB creation...");
41981 + return 0;
41983 + if (TeApplicationInit () != E_OK)
41984 + zlog_err ("TE application init failed");
41986 + if (InitInterfaceDB () != E_OK)
41987 + zlog_err ("cannot initiate I/F DB");
41989 + rsvp_zebra_init ();
41990 + rsvp_te_comm_init ();
41992 + sort_node ();
41994 + /* Get configuration file. */
41995 + vty_read_config (config_file, config_default);
41997 + /* Start execution only if not in dry-run mode */
41998 + if (dryrun)
41999 + return (0);
42001 + /* Change to the daemon program. */
42002 + if (daemon_mode)
42003 + daemon (0, 0);
42005 + /* Process id file create. */
42006 + pid_output (pid_file);
42008 + /* Create VTY socket */
42009 + vty_serv_sock (vty_addr, vty_port, RSVP_VTYSH_PATH);
42011 + /* Print banner. */
42012 + zlog_notice ("RSVPd %s starting: vty@%d", QUAGGA_VERSION, vty_port);
42014 + /* Fetch next active thread. */
42015 + while (thread_fetch (master, &thread))
42016 + thread_call (&thread);
42018 + /* Not reached. */
42019 + return (0);
42021 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_packet.h quagga-mpls/rsvpd/rsvp_packet.h
42022 --- quagga/rsvpd/rsvp_packet.h 1969-12-31 18:00:00.000000000 -0600
42023 +++ quagga-mpls/rsvpd/rsvp_packet.h 2007-07-02 23:14:43.000000000 -0500
42024 @@ -0,0 +1,499 @@
42025 +#ifndef _RSVP_PACKET_H_
42026 +#define _RSVP_PACKET_H_
42028 +#define RSVP_IP_PROTOCOL 46
42030 +#define COMMON_CTYPE 1
42032 +#define SESSION_CLASS 1
42033 +#define RSVP_HOP_CLASS 3
42034 +#define INTEGRITY_CLASS 4
42035 +#define TIME_VALUES_CLASS 5
42036 +#define ERR_SPEC_CLASS 6
42037 +#define SCOPE_CLASS 7
42038 +#define STYLE_CLASS 8
42039 +#define FLOW_SPEC_CLASS 9
42040 +#define FILTER_SPEC_CLASS 10
42041 +#define SENDER_TEMPLATE_CLASS 11
42042 +#define SENDER_TSPEC_CLASS 12
42043 +#define ADSPEC_CLASS 13
42044 +#define POLICY_DATA_CLASS 14
42045 +#define RESV_CONF_CLASS 15
42046 +#define LABEL_CLASS 16
42047 +#define LABEL_REQUEST_CLASS 19
42048 +#define EXPLICIT_ROUTE_CLASS 20
42049 +#define RECORDED_ROUTE_CLASS 21
42050 +#define SESSION_ATTRIBUTE_CLASS 207
42052 +#define SESSION_CTYPE 7
42053 +#define SENDER_TEMPLATE_CTYPE 7
42054 +#define SENDER_TSPEC_CTYPE 2
42056 +#define FLOW_SPEC_INTSERV_CTYPE 2
42058 +#define SESSION_ATTRIBUTES_RA_CLASS_TYPE 1
42059 +#define SESSION_ATTRIBUTES_CLASS_TYPE 7
42063 +#define SESSION_LSP_IPV4_CTYPE 7
42064 +#define SENDER_TEMPLATE_LSP_IPV4_CTYPE 7
42065 +#define FILTER_SPEC_LSP_IPV4_CTYPE 7
42066 +#define SESSION_ATTRIBUTES_IPV4_CTYPE 7
42067 +#define SESSION_ATTRIBUTES_RA_IPV4_CTYPE 1
42069 +#define RSVP_VERSION (1 << 4)
42071 +#define LOCAL_PROTECTION_DESIRED 0x01
42072 +#define LABEL_RECORDING_DESIRED 0x02
42073 +#define SE_STYLE_DESIRED 0x04
42075 +typedef struct
42077 + uns8 VersionFlags;
42078 + uns8 MsgType;
42079 + uns16 CheckSum;
42080 + uns8 SendTTL;
42081 + uns8 Resvd;
42082 + uns16 RsvpLength;
42083 +} RSVP_COMMON_HDR;
42085 +#define PATH_MSG 1
42086 +#define RESV_MSG 2
42087 +#define PATH_ERR_MSG 3
42088 +#define RESV_ERR_MSG 4
42089 +#define PATH_TEAR_MSG 5
42090 +#define RESV_TEAR_MSG 6
42091 +#define RESV_CONF_MSG 7
42093 +typedef struct
42095 + uns16 Length;
42096 + uns8 ClassNum;
42097 + uns8 CType;
42098 +} OBJ_HDR;
42101 +typedef struct
42103 + IPV4_ADDR Dest;
42104 + uns16 Resvd;
42105 + uns16 TunnelId;
42106 + IPV4_ADDR ExtTunelId;
42107 +} SESSION_OBJ;
42109 +typedef struct
42111 + IPV4_ADDR PHop;
42112 + uns32 LIH;
42113 +} RSVP_HOP_OBJ;
42115 +typedef struct
42117 + uns32 TimeValues;
42118 +} TIME_VALUES_OBJ;
42120 +typedef struct
42122 + uns32 IpAddrNumber;
42123 + IPV4_ADDR *Addresses;
42124 +} SCOPE_OBJ;
42127 +typedef struct
42129 + uns8 Flags;
42130 + uns8 OptionVector1;
42131 + uns16 OptionVector2;
42132 +} STYLE_OBJ;
42134 +#define SE_STYLE_BITS 0x12
42135 +#define FF_STYLE_BITS 0x0A
42137 +typedef struct
42139 + uns16 VersionResvd;
42140 + uns16 MessageLength;
42141 +} MSG_HDR;
42143 +typedef struct
42145 + uns8 ServHdr;
42146 + uns8 Resvd;
42147 + uns16 ServLength;
42148 +} SERV_HDR;
42150 +typedef struct
42152 + uns8 ParamID;
42153 + uns8 ParamFlags;
42154 + uns16 ParamLength;
42155 +} PARAM_HDR;
42157 +typedef struct
42159 + float TockenBucketRate;
42160 + float TockenBucketSize;
42161 + float PeakDataRate;
42162 + float MinPolicedUnit;
42163 + float MaxPacketSize;
42164 +} CTRL_LOAD_FLOW_SPEC;
42166 +typedef struct
42168 + CTRL_LOAD_FLOW_SPEC CtrlLoad;
42169 + PARAM_HDR GuarSpecificParamHdr;
42170 + float Rate;
42171 + uns32 SlackTerm;
42172 +} GUAR_FLOW_SPEC;
42174 +typedef struct
42176 + MSG_HDR MsgHdr;
42177 + SERV_HDR ServHdr;
42178 + PARAM_HDR ParamHdr;
42179 + union
42181 + CTRL_LOAD_FLOW_SPEC CtrlLoad;
42182 + GUAR_FLOW_SPEC Guar;
42183 + } u;
42184 +} FLOW_SPEC_OBJ;
42186 +typedef struct
42188 + IPV4_ADDR IpAddr;
42189 + uns16 Resvd;
42190 + uns16 LspId;
42191 +} SENDER_TEMPLATE_OBJ;
42193 +typedef SENDER_TEMPLATE_OBJ FILTER_SPEC_OBJ;
42195 +#define SENDER_TSPEC_MSG_FORMAT 0
42196 +#define SENDER_TSPEC_MSG_LENGTH 7
42197 +#define SENDER_TSPEC_SERV_NUMBER 5
42198 +#define SENDER_TSPEC_DATA_LENGTH 6
42199 +#define SENDER_TSPEC_TOCKEN_BUCKET_PARAM_ID 127
42200 +#define SENDER_TSPEC_TOCKEN_BUCKET_PARAM_LENGTH 5
42202 +#define FLOW_SPEC_MSG_FORMAT 0
42203 +#define FLOW_SPEC_MSG_LENGTH 7
42204 +#define FLOW_SPEC_GUAR_SERV_NUMBER 2
42205 +#define FLOW_SPEC_CTRL_LOAD_SERV_NUMBER 5
42206 +#define FLOW_SPEC_DATA_LENGTH 6
42207 +#define FLOW_SPEC_TOCKEN_BUCKET_PARAM_ID 127
42208 +#define FLOW_SPEC_TOCKEN_BUCKET_PARAM_LENGTH 5
42210 +typedef struct
42212 + MSG_HDR MessageHdr;
42213 + SERV_HDR ServHdr;
42214 + PARAM_HDR ParamHdr;
42215 + float TockenBucketRate;
42216 + float TockenBucketSize;
42217 + float PeakDataRate;
42218 + uns32 MinPolicedUnit;
42219 + uns32 MaxPacketSize;
42220 +} SENDER_TSPEC_OBJ;
42222 +typedef struct
42224 + uns32 Label;
42225 +} LABEL_OBJ;
42227 +typedef struct
42229 + uns16 Resvd;
42230 + uns16 L3Pid;
42231 +} LABEL_REQUEST_OBJ;
42233 +typedef struct
42235 + uns8 LType;
42236 + uns8 Length;
42237 +} ER_SUBOBJ_HDR;
42239 +typedef struct
42241 + IPV4_ADDR IpAddress;
42242 + uns8 PrefixLength;
42243 + uns8 Resvd;
42244 +} ER_IPV4_SUBOBJ;
42246 +typedef struct
42248 + uns32 AsNumber;
42249 +} ER_AS_SUBOBJ;
42251 +typedef struct _er_subobj_
42253 + ER_SUBOBJ_HDR SubObjHdr;
42254 + union
42256 + ER_IPV4_SUBOBJ Ipv4;
42257 + ER_AS_SUBOBJ AS;
42258 + } u;
42259 + struct _er_subobj_ *next;
42260 +} ER_SUBOBJ;
42262 +typedef struct
42264 + uns8 SubObjNumber;
42265 + ER_SUBOBJ *er;
42266 +} ER_OBJ;
42268 +typedef struct
42270 + uns8 Type;
42271 + uns8 Length;
42272 +} RR_SUBOBJ_HDR;
42274 +typedef struct
42276 + IPV4_ADDR IpAddr;
42277 + uns8 PrefixLen;
42278 + uns8 Flags;
42279 +} RR_IPV4_SUBOBJ;
42281 +typedef struct
42283 + uns8 Flags;
42284 + uns8 CType;
42285 + uns32 Label;
42286 +} RR_LABEL_SUBOBJ;
42288 +typedef struct _rr_subobj_
42290 + RR_SUBOBJ_HDR SubObjHdr;
42291 + union
42293 + RR_IPV4_SUBOBJ Ipv4;
42294 + RR_LABEL_SUBOBJ Label;
42295 + } u;
42296 + struct _rr_subobj_ *next;
42297 +} RR_SUBOBJ;
42299 +typedef struct
42301 + RR_SUBOBJ *rr;
42302 +} RR_OBJ;
42304 +typedef struct
42306 + uns8 SetPrio;
42307 + uns8 HoldPrio;
42308 + uns8 Flags;
42309 + uns8 NameLength;
42310 + char *SessionName;
42311 +} SESSION_ATTR;
42313 +typedef struct
42315 + uns32 ExcludeAny;
42316 + uns32 IncludeAny;
42317 + uns32 IncludeAll;
42318 + uns8 SetPrio;
42319 + uns8 HoldPrio;
42320 + uns8 Flags;
42321 + uns8 NameLength;
42322 + char *SessionName;
42323 +} SESSION_ATTR_RA;
42325 +typedef struct
42327 + uns8 CType;
42328 + union
42330 + SESSION_ATTR SessAttr;
42331 + SESSION_ATTR_RA SessAttrRa;
42332 + } u;
42333 +} SESSION_ATTRIBUTES_OBJ;
42335 +typedef struct
42337 + uns8 PerServHdr;
42338 + uns8 BreakBitAndResvd;
42339 + uns16 Length;
42340 +} PER_SERV_HDR;
42342 +typedef struct
42344 + PER_SERV_HDR PerServHdr;
42345 + PARAM_HDR Param4Hdr;
42346 + uns32 IS_HopCount;
42347 + PARAM_HDR Param6Hdr;
42348 + float PathBW;
42349 + PARAM_HDR Param8Hdr;
42350 + uns32 MinPathLatency;
42351 + PARAM_HDR Param10Hdr;
42352 + uns32 ComposedMTU;
42353 +} ADSPEC_GEN;
42355 +typedef struct
42357 + PER_SERV_HDR PerServHdr;
42358 + PARAM_HDR Param133Hdr;
42359 + uns32 Ctot;
42360 + PARAM_HDR Param134Hdr;
42361 + uns32 Dtot;
42362 + PARAM_HDR Param135Hdr;
42363 + uns32 Csum;
42364 + PARAM_HDR Param136Hdr;
42365 + uns32 Dsum;
42366 +} GUAR_ADSPEC;
42368 +typedef struct
42370 + uns8 CType;
42371 + uns16 Resvd;
42372 + uns16 MsgLen;
42373 + ADSPEC_GEN AdSpecGen;
42374 + GUAR_ADSPEC GuarAdSpec;
42375 +} ADSPEC_OBJ;
42377 +typedef struct
42379 + IPV4_ADDR IpAddr;
42380 +} RESV_CONF_OBJ;
42382 +typedef struct
42384 + IPV4_ADDR IpAddr;
42385 + uns8 Flags;
42386 + uns8 ErrCode;
42387 + uns16 ErrVal;
42388 +} ERR_SPEC_OBJ;
42390 +#define CONFIRMATION_ERR_CODE 0
42391 +#define ADMISSION_CTRL_FAILURE_ERR_CODE 1
42392 +#define POLICY_CTRL_FAILURE_ERR_CODE 2
42393 +#define NO_PATH_INFO_4_RESV_ERR_CODE 3
42394 +#define NO_SENDER_INFO_4_RESV 4
42395 +#define CONFLICTING_RESV_STYLES_ERR_CODE 5
42396 +#define UNKNOWN_RESV_STYLE_ERR_CODE 6
42397 +#define CONFLICTING_DEST_PORTS_ERR_CODE 7
42398 +#define CONFLICTING_SENDER_PORTS_ERR_CODE 8
42399 +#define SERVICE_PREEMPTED_ERR_CODE 12
42400 +#define UNKNOWN_OBJ_CLASS_ERR_CODE 13
42401 +#define UNKNOWN_OBJ_CTYPE_ERR_CODE 14
42402 +#define API_ERR_CODE 20
42403 +#define TRAFFIC_CTRL_ERR_CODE 21
42404 +#define TRAFFIC_CTRL_SYSTEM_ERR_CODE 22
42405 +#define RSVP_SYSTEM_ERR_CODE 23
42406 +#define ROUTING_PROBLEM_ERR_CODE 24
42407 +#define NOTIFY_ERR_CODE 25
42409 +#define GLB_DEFINED_SUB_CODE_FLAG 0x0000
42410 +#define ORG_SPECIFIC_SUB_CODE_FLAG 0x8000
42411 +#define SRV_SPECIFIC_SUB_CODE_FLAG 0xC000
42412 +#define LOCAL_STATE_MAY_BE_UPDATED_FLAG 0x1000
42414 +#define DELAY_BOUND_CANNOT_BE_MET 0x0001
42415 +#define BW_UNAVAILABLE 0x0002
42416 +#define MTU_UNAVAILABLE 0x0003
42418 +#define SERVICE_CONFLICT 0x0001
42419 +#define SERVICE_UNSUPPORTED 0x0002
42420 +#define BAD_FLOW_SPEC_VAL 0x0003
42421 +#define BAD_TSPEC_VAL 0x0004
42422 +#define BAD_ADSPEC_VAL 0x0005
42424 +#define BAD_EXPLICIT_ROUTE_OBJ 0x0001
42425 +#define BAD_STRICT_NODE 0x0002
42426 +#define BAD_LOOSE_NODE 0x0003
42427 +#define BAD_INITIAL_SUBOBJ 0x0004
42428 +#define NO_ROUTE_AVAILABLE 0x0005
42429 +#define UNACCEPTABLE_LABEL_VAL 0x0006
42430 +#define RRO_INIDICATED_ROUTING_LOOP 0x0007
42431 +#define NON_RSVP_ROUTER_IN_PATH 0x0008
42432 +#define LABEL_ALLOCATION_FAILURE 0x0009
42433 +#define UNSUPPORTED_L3PID 0x000A
42435 +#define RRO_TOO_LARGE_4_MTU 0x0001
42436 +#define RRO_NOTIFICATION 0x0002
42437 +#define TUNNEL_LOCALLY_REPAIRED 0x0003
42439 +typedef struct _opaque_obj_list_
42441 + OBJ_HDR ObjHdr;
42442 + void *pData;
42443 + struct _opaque_obj_list_ *next;
42444 +} OPAQUE_OBJ_LIST;
42446 +typedef OPAQUE_OBJ_LIST POLICY_DATA_OBJ;
42447 +typedef OPAQUE_OBJ_LIST INTEGRITY_OBJ;
42449 +//typedef SENDER_TEMPLATE_OBJ FILTER_SPEC_OBJ;
42450 +//typedef struct SENDER_TSPEC FLOW_SPEC_OBJ;
42452 +struct _phop_resv_refresh_list_;
42453 +struct _rsb_;
42455 +typedef struct
42457 + FILTER_SPEC_OBJ FilterSpec;
42458 + LABEL_OBJ ReceivedLabel; /* received with RESV */
42459 + LABEL_OBJ SentLabel; /* sent with RESV (allocated upon PATH) */
42460 + RR_OBJ Rro;
42461 + uns32 AgeOutValue;
42462 + struct thread *AgeOutTimer;
42463 + FLOW_SPEC_OBJ FlowSpec;
42464 + uns8 NewFlowSpecValid;
42465 + FLOW_SPEC_OBJ NewFlowSpec;
42466 + FLOW_SPEC_OBJ BlockadeFlowSpec;
42467 + struct _phop_resv_refresh_list_ *pPHopResvRefreshList;
42468 + struct _effective_flow_ *pEffectiveFlow; /* for SE only */
42469 + struct _psb_ *pPsb;
42470 + uns8 ToBeDeleted;
42471 + uns32 BlocadeValue;
42472 + struct thread *BlocadeTimer;
42473 + uns8 Blocked;
42474 +} FILTER_SPEC_DATA;
42476 +typedef struct _filter_list_
42478 + FILTER_SPEC_DATA *pFilterSpecData;
42479 + struct _filter_list_ *next;
42480 +} FILTER_LIST;
42482 +typedef struct
42484 + SESSION_OBJ Session;
42485 + RSVP_HOP_OBJ ReceivedRsvpHop;
42486 + RSVP_HOP_OBJ SentRsvpHop;
42487 + TIME_VALUES_OBJ TimeValues;
42488 + ER_OBJ ReceivedEro;
42489 + ER_OBJ SentEro;
42490 + LABEL_REQUEST_OBJ LabelRequest;
42491 + SESSION_ATTRIBUTES_OBJ SessionAttributes;
42492 + SENDER_TEMPLATE_OBJ SenderTemplate;
42493 + SENDER_TSPEC_OBJ SenderTSpec;
42494 + ADSPEC_OBJ ReceivedAdSpec;
42495 + ADSPEC_OBJ SentAdSpec;
42496 + RR_OBJ ReceivedRro;
42497 + RR_OBJ AddedRro;
42498 + RESV_CONF_OBJ ResvConf;
42499 + STYLE_OBJ Style;
42500 + FILTER_LIST *pFilterList;
42501 + INTEGRITY_OBJ *pIntegrityObj;
42502 + POLICY_DATA_OBJ *pPolicyDataObj;
42503 + OPAQUE_OBJ_LIST *pOpaqueObjList;
42504 + ERR_SPEC_OBJ ErrorSpec;
42505 +} RSVP_PKT;
42507 +#define ERO_SUBTYPE_IPV4 1
42508 +#define ERO_SUBTYPE_AS 32
42510 +#define RRO_SUBTYPE_IPV4 1
42511 +#define RRO_SUBTYPE_LABEL 3
42513 +typedef struct _rsvp_pkt_queue_
42515 + uns8 MsgType;
42516 + RSVP_PKT *pRsvpPkt;
42517 + uns32 InIfIndex;
42518 + IPV4_ADDR SourceIp;
42519 + uns8 ttl;
42520 + struct _rsvp_pkt_queue_ *next;
42521 +} RSVP_PKT_QUEUE;
42523 +#endif /* !defined (_RSVP_PKT_H_) */
42524 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_path.c quagga-mpls/rsvpd/rsvp_path.c
42525 --- quagga/rsvpd/rsvp_path.c 1969-12-31 18:00:00.000000000 -0600
42526 +++ quagga-mpls/rsvpd/rsvp_path.c 2007-07-02 22:50:59.000000000 -0500
42527 @@ -0,0 +1,1225 @@
42528 +/* Module: rsvp_path.c
42529 + Contains: RSVP PATH, PATH TEAR and PATH ERROR message
42530 + processing functions.
42531 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
42532 + */
42533 +#include "rsvp.h"
42534 +#include "thread.h"
42536 +uns32 PathRefreshInterval = 30; /* sec */
42537 +uns32 RefreshMultiple = /*3 */ 12;
42539 +extern RSVP_STATISTICS RsvpStatistics;
42540 +extern struct thread_master *master;
42542 +static PATRICIA_TREE PsbTree;
42544 +static void PrepareAndSendMsg2TE (PSB * pPsb);
42545 +static E_RC StartPathAgeOutTimer (uns32 time, struct thread **pTimerId,
42546 + void *data);
42547 +static E_RC StopPathAgeOutTimer (struct thread **pTimerId);
42548 +static E_RC StartPathRefreshTimer (uns32 time, struct thread **pTimerId,
42549 + void *data);
42550 +static E_RC StopPathRefreshTimer (struct thread **pTimerId);
42551 +static void PrepareAndSendLabelReleaseMsg2TE (PSB * pPsb);
42552 +static void PrepareAndSendPathErrNotificationMsg2TE (PSB * pPsb,
42553 + ERR_SPEC_OBJ *
42554 + pErrSpecObj);
42556 +E_RC
42557 +InitRsvpPathMessageProcessing ()
42559 + PATRICIA_PARAMS params;
42561 + memset (&params, 0, sizeof (PATRICIA_PARAMS));
42562 + params.key_size = sizeof (PSB_KEY);
42563 + if (patricia_tree_init (&PsbTree, &params) != E_OK)
42565 + zlog_err ("Cannot initiate PSB tree");
42566 + return E_ERR;
42568 + return E_OK;
42571 +PSB *
42572 +GetNextPSB (PSB_KEY * pPsbKey)
42574 + return (PSB *) patricia_tree_getnext (&PsbTree, (const uns8 *) pPsbKey);
42577 +PSB *
42578 +FindPsb (PSB_KEY * pPsbKey)
42580 + return (PSB *) patricia_tree_get (&PsbTree, (uns8 *) pPsbKey);
42583 +PSB *
42584 +NewPsb (PSB_KEY * pPsbKey)
42586 + PSB *pPsb = (PSB *) XMALLOC (MTYPE_RSVP, sizeof (PSB));
42588 + if (pPsb == NULL)
42589 + return NULL;
42590 + memset (pPsb, 0, sizeof (PSB));
42591 + pPsb->PsbKey = *pPsbKey;
42592 + pPsb->Node.key_info = (uns8 *) & pPsb->PsbKey;
42593 + if (patricia_tree_add (&PsbTree, &pPsb->Node) != E_OK)
42595 + XFREE (MTYPE_RSVP, pPsb);
42596 + zlog_err ("Cannot add node to patricia tree %s %d", __FILE__, __LINE__);
42597 + return NULL;
42599 + RsvpStatistics.NewPsbCount++;
42600 + return pPsb;
42603 +E_RC
42604 +RemovePsb (PSB_KEY * pPsbKey)
42606 + PSB *pPsb = FindPsb (pPsbKey);
42608 + if (pPsb == NULL)
42610 + zlog_err ("Cannot get PSB %s %d", __FILE__, __LINE__);
42611 + return E_ERR;
42613 + if (patricia_tree_del (&PsbTree, &pPsb->Node) != E_OK)
42615 + zlog_err ("Cannot delete node from patricia %s %d", __FILE__, __LINE__);
42616 + return E_ERR;
42618 + return E_OK;
42621 +void
42622 +PsbDequeueAndInvokeMessages (PSB * pPsb)
42624 + RSVP_PKT_QUEUE *pQueuedItem;
42625 + if (!pPsb)
42626 + return;
42628 + while ((pPsb->TE_InProcess == FALSE) &&
42629 + (((pPsb->pFilterSpecData != NULL) &&
42630 + (pPsb->pFilterSpecData->pEffectiveFlow != NULL) &&
42631 + (pPsb->pFilterSpecData->pEffectiveFlow->TE_InProcess == FALSE)) ||
42632 + ((pPsb->pFilterSpecData != NULL)
42633 + && (pPsb->pFilterSpecData->pEffectiveFlow == NULL))
42634 + || (pPsb->pFilterSpecData == NULL))
42635 + && ((pQueuedItem = DequeueRsvpPacket (&pPsb->packet_queue)) != NULL))
42637 + RSVP_PKT *pRsvpPkt;
42638 + uns8 MsgType;
42639 + uns32 InIfIndex = pQueuedItem->InIfIndex;
42640 + IPV4_ADDR SourceIp = pQueuedItem->SourceIp;
42641 + uns8 ttl = pQueuedItem->ttl;
42642 + pRsvpPkt = pQueuedItem->pRsvpPkt;
42643 + MsgType = pQueuedItem->MsgType;
42644 + XFREE (MTYPE_RSVP, pQueuedItem);
42645 + if (MsgType == PATH_MSG)
42647 + ProcessRsvpPathMessage (pRsvpPkt, InIfIndex, SourceIp, ttl);
42649 + else if (MsgType == PATH_TEAR_MSG)
42651 + ProcessRsvpPathTearMessage (pRsvpPkt, InIfIndex, SourceIp, ttl);
42652 + return;
42654 + else if (MsgType == RESV_MSG)
42656 + ProcessRsvpResvMessage (pRsvpPkt);
42658 + else if (MsgType == RESV_TEAR_MSG)
42660 + ProcessRsvpResvTearMessage (pRsvpPkt);
42662 + else if (MsgType == RESV_ERR_MSG)
42664 + ProcessRsvpResvErrMessage (pRsvpPkt);
42666 + else
42667 + zlog_err ("Unknown message type %d %s %d", MsgType, __FILE__,
42668 + __LINE__);
42672 +static int RsvpPathRefreshTimer (struct thread *);
42674 +E_RC
42675 +RsvpPathRefresh (PSB * pPsb)
42677 + E_RC rc = E_OK;
42678 + zlog_info ("entering RsvpPathRefresh");
42679 + zlog_info ("Session.Dest %x .TunnelId %x .ExtTunnelId %x .Src %x .LspId %x",
42680 + pPsb->PsbKey.Session.Dest,
42681 + pPsb->PsbKey.Session.TunnelId,
42682 + pPsb->PsbKey.Session.ExtTunelId,
42683 + pPsb->PsbKey.SenderTemplate.IpAddr,
42684 + pPsb->PsbKey.SenderTemplate.LspId);
42685 + if ((pPsb->pSentBuffer == NULL) || (pPsb->SentBufferLen == 0))
42687 + if (EncodeAndSendRsvpPathMessage (&pPsb->OldPacket,
42688 + pPsb->NextHop,
42689 + pPsb->OutIfIndex,
42690 + pPsb->ttl - 1,
42691 + &pPsb->pSentBuffer,
42692 + &pPsb->SentBufferLen) != E_OK)
42694 + zlog_err ("Cannot encode/send message");
42695 + rc = E_ERR;
42698 + else
42700 + if (SendRawData
42701 + (pPsb->pSentBuffer, pPsb->SentBufferLen, pPsb->NextHop,
42702 + pPsb->OutIfIndex, pPsb->ttl - 1, TRUE) != E_OK)
42704 + zlog_err ("Cannot send raw data %s %d", __FILE__, __LINE__);
42705 + rc = E_ERR;
42708 + if (StopPathRefreshTimer (&pPsb->PathRefreshTimer) != E_OK)
42710 + zlog_err ("Cannot stop PathRefreshTimer %s %d", __FILE__, __LINE__);
42711 + return E_ERR;
42714 + if (StartPathRefreshTimer
42715 + (pPsb->RefreshValue, &pPsb->PathRefreshTimer, pPsb) != E_OK)
42717 + zlog_err ("Cannot add timer %s %d", __FILE__, __LINE__);
42718 + rc = E_ERR;
42720 + zlog_info ("leaving RsvpPathRefresh");
42721 + return rc;
42724 +static int
42725 +RsvpPathRefreshTimer (struct thread *thread)
42727 + PSB *pPsb = THREAD_ARG (thread);
42728 + if (pPsb == NULL)
42730 + zlog_err ("pPsb is NULL %s %d", __FILE__, __LINE__);
42731 + return;
42733 + zlog_info ("entering RsvpPathRefreshTimer");
42734 + memset (&pPsb->PathRefreshTimer, 0, sizeof (struct thread *));
42735 + if (RsvpPathRefresh (pPsb) != E_OK)
42737 + zlog_err ("an error o RsvpPathRefresh");
42739 + zlog_info ("leaving RsvpPathRefreshTimer");
42742 +E_RC
42743 +RsvpPathPopERO (RSVP_PKT * pRsvpPkt)
42745 + ER_SUBOBJ *pErSubObj, *pErSubObjPrev = NULL, *pErSubObjNext;
42746 + uns8 ExitFlag = FALSE;
42748 + pErSubObj = pRsvpPkt->ReceivedEro.er;
42749 + while (pErSubObj != NULL)
42751 + switch (pErSubObj->SubObjHdr.LType & 0x7F)
42753 + case ERO_SUBTYPE_IPV4:
42754 + zlog_info ("checking for abstract node %x",
42755 + pErSubObj->u.Ipv4.IpAddress);
42756 + if (IsAbstractNode
42757 + (pErSubObj->u.Ipv4.IpAddress,
42758 + pErSubObj->u.Ipv4.PrefixLength) == TRUE)
42760 + zlog_info ("FOUND...");
42761 + if (pErSubObjPrev == NULL)
42763 + pRsvpPkt->ReceivedEro.er = pRsvpPkt->ReceivedEro.er->next;
42764 + pErSubObjNext = pRsvpPkt->ReceivedEro.er;
42766 + else
42768 + pErSubObjPrev->next = pErSubObj->next;
42769 + pErSubObjNext = pErSubObj->next;
42771 + XFREE (MTYPE_RSVP, pErSubObj);
42772 + pErSubObj = pErSubObjNext;
42774 + else
42775 + ExitFlag = TRUE;
42776 + break;
42777 + default:
42778 + ExitFlag = TRUE;
42780 + if (ExitFlag == TRUE)
42781 + break;
42783 + return E_OK;
42786 +uns8
42787 +CompareERO (ER_SUBOBJ * pErSubObj1, ER_SUBOBJ * pErSubObj2, uns16 HopsNum)
42789 + while ((pErSubObj1 != NULL) && (pErSubObj2 != NULL))
42791 + if (memcmp (&pErSubObj1->SubObjHdr,
42792 + &pErSubObj2->SubObjHdr, sizeof (ER_SUBOBJ_HDR)) == 0)
42794 + switch (pErSubObj1->SubObjHdr.LType & 0x7F)
42796 + case ERO_SUBTYPE_IPV4:
42797 + if (memcmp (&pErSubObj1->u.Ipv4,
42798 + &pErSubObj2->u.Ipv4, sizeof (ER_IPV4_SUBOBJ)) != 0)
42800 + zlog_info ("IP address differs %x %x...",
42801 + pErSubObj1->u.Ipv4.IpAddress,
42802 + pErSubObj2->u.Ipv4.IpAddress);
42803 + return TRUE;
42805 + break;
42806 + case ERO_SUBTYPE_AS:
42807 + if (memcmp (&pErSubObj1->u.AS,
42808 + &pErSubObj2->u.AS, sizeof (ER_AS_SUBOBJ)) != 0)
42810 + return TRUE;
42812 + break;
42813 + default:
42814 + return FALSE;
42817 + if (HopsNum == 1)
42819 + return FALSE;
42821 + pErSubObj1 = pErSubObj1->next;
42822 + pErSubObj2 = pErSubObj2->next;
42825 + if (((pErSubObj1 == NULL) &&
42826 + (pErSubObj2 != NULL)) ||
42827 + ((pErSubObj1 != NULL) && (pErSubObj2 == NULL)))
42829 + zlog_info ("Number of elements differs...");
42830 + return TRUE;
42832 + return FALSE;
42835 +static int
42836 +RsvpPathAgeOut (struct thread *thread)
42838 + PSB *pPsb = THREAD_ARG (thread);
42840 + zlog_info ("entering RsvpPathAgeOut");
42842 + // jleu: timer is not rescheduled
42843 + memset (&pPsb->AgeOutTimer, 0, sizeof (struct thread *));
42845 + if (pPsb->OutIfIndex != 0)
42847 + if (EncodeAndSendRsvpPathTearMessage
42848 + (&pPsb->OldPacket, pPsb->NextHop, pPsb->OutIfIndex,
42849 + pPsb->ttl - 1) != E_OK)
42851 + zlog_err ("an error on EncodeAndSendRsvpPathTearMessage %s %d",
42852 + __FILE__, __LINE__);
42855 + if (DeleteSender (pPsb) != E_OK)
42857 + zlog_err ("an error on DeleteSender %s %d", __FILE__, __LINE__);
42859 + RsvpStatistics.PsbAgeOutCount++;
42860 + zlog_info ("leaving RsvpPathAgeOut");
42863 +uns8
42864 +IsEgress (PSB * pPsb)
42866 + return IsAbstractNode (pPsb->OldPacket.Session.Dest, 32);
42869 +E_RC
42870 +ProcessRsvpPathMessage (RSVP_PKT * pRsvpPkt, uns32 IfIndex,
42871 + IPV4_ADDR SrcIpAddr, uns8 ttl)
42873 + PSB *pPsb;
42874 + PSB_KEY PsbKey;
42875 + RSVP_PKT_QUEUE *pQueuedItem;
42876 + uns8 ApplicationTrapFlag = FALSE;
42877 + zlog_info ("entering ProcessRsvpPathMessage");
42878 + RsvpStatistics.PathMsgCount++;
42879 + memset (&PsbKey, 0, sizeof (PSB_KEY));
42881 + PsbKey.Session = pRsvpPkt->Session;
42882 + PsbKey.SenderTemplate = pRsvpPkt->SenderTemplate;
42883 + zlog_info ("Session.Dest %x .TunnelId %x .ExtTunnelId %x .Src %x .LspId %x",
42884 + PsbKey.Session.Dest,
42885 + PsbKey.Session.TunnelId,
42886 + PsbKey.Session.ExtTunelId,
42887 + PsbKey.SenderTemplate.IpAddr, PsbKey.SenderTemplate.LspId);
42888 + if ((pPsb = FindPsb (&PsbKey)) == NULL)
42890 + if ((pPsb = NewPsb (&PsbKey)) == NULL)
42892 + zlog_err ("Cannot create PSB");
42893 + FreeRsvpPkt (pRsvpPkt);
42894 + return E_ERR;
42896 + ApplicationTrapFlag = TRUE;
42897 + memcpy (&pPsb->OldPacket.Session, &pRsvpPkt->Session,
42898 + sizeof (SESSION_OBJ));
42899 + memcpy (&pPsb->OldPacket.SenderTemplate, &pRsvpPkt->SenderTemplate,
42900 + sizeof (SENDER_TEMPLATE_OBJ));
42901 + memcpy (&pPsb->OldPacket.LabelRequest, &pRsvpPkt->LabelRequest,
42902 + sizeof (LABEL_REQUEST_OBJ));
42903 + pPsb->RefreshValue =
42904 + PathRefreshInterval + RefreshRandomize (PathRefreshInterval);
42906 + else
42908 + if (StopPathAgeOutTimer (&pPsb->AgeOutTimer) != E_OK)
42910 + zlog_err ("Cannot stop Ageout timer");
42912 + if (pPsb->TE_InProcess == TRUE)
42914 + if ((pQueuedItem =
42915 + (RSVP_PKT_QUEUE *) XMALLOC (MTYPE_RSVP,
42916 + sizeof (RSVP_PKT_QUEUE))) == NULL)
42918 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
42919 + return E_ERR;
42921 + pQueuedItem->MsgType = PATH_MSG;
42922 + pQueuedItem->InIfIndex = IfIndex;
42923 + pQueuedItem->pRsvpPkt = pRsvpPkt;
42924 + pQueuedItem->SourceIp = SrcIpAddr;
42925 + pQueuedItem->ttl = ttl;
42926 + pQueuedItem->next = NULL;
42927 + if (EnqueueRsvpPacket (pQueuedItem, &pPsb->packet_queue) != E_OK)
42929 + zlog_err ("Cannot enqueue Path");
42931 + return E_OK;
42934 + pPsb->InIfIndex = IfIndex;
42935 + pPsb->PrevHop = pRsvpPkt->ReceivedRsvpHop.PHop /*SrcIpAddr */ ;
42936 + pPsb->ttl = ttl;
42937 + if (CheckRRO4Loop (pRsvpPkt->ReceivedRro.rr) != E_OK)
42939 + zlog_err ("Loop detected");
42940 + if (GeneratePathErrMessage
42941 + (pPsb, ROUTING_PROBLEM_ERR_CODE,
42942 + RRO_INIDICATED_ROUTING_LOOP) != E_OK)
42944 + zlog_err ("Cannot generate PAthErr message %s %d", __FILE__,
42945 + __LINE__);
42947 + if (DeleteSender (pPsb) != E_OK)
42949 + zlog_err ("An error on DeleteSender %s %d", __FILE__, __LINE__);
42951 + FreeRsvpPkt (pRsvpPkt);
42952 + return E_ERR;
42954 + if (memcmp
42955 + (&pRsvpPkt->TimeValues, &pPsb->OldPacket.TimeValues,
42956 + sizeof (TIME_VALUES_OBJ)) != 0)
42958 + uns32 val;
42959 + memcpy (&pPsb->OldPacket.TimeValues, &pRsvpPkt->TimeValues,
42960 + sizeof (TIME_VALUES_OBJ));
42962 + val = (uns32) pPsb->OldPacket.TimeValues.TimeValues / 10000;
42963 + /* 3*R: */
42964 + val *= 3;
42965 + /* (2M+1) * (3*R): */
42966 + val = (2 * RefreshMultiple + 1) * val;
42967 + /* and divide by 4 to get (M + 0.5) * (1.5 * R) */
42968 + pPsb->AgeOutValue = val >> 2;
42969 + zlog_info ("AgeOut value %d", pPsb->AgeOutValue);
42972 + if (memcmp (&pRsvpPkt->ReceivedRsvpHop,
42973 + &pPsb->OldPacket.ReceivedRsvpHop, sizeof (RSVP_HOP_OBJ)) != 0)
42975 + memcpy (&pPsb->OldPacket.ReceivedRsvpHop, &pRsvpPkt->ReceivedRsvpHop,
42976 + sizeof (RSVP_HOP_OBJ));
42977 + pPsb->PathRefreshFlag = TRUE;
42978 + pPsb->ResvRefreshFlag = TRUE;
42980 + if (memcmp (&pRsvpPkt->SenderTSpec,
42981 + &pPsb->OldPacket.SenderTSpec, sizeof (SENDER_TSPEC_OBJ)) != 0)
42983 + memcpy (&pPsb->OldPacket.SenderTSpec, &pRsvpPkt->SenderTSpec,
42984 + sizeof (SENDER_TSPEC_OBJ));
42985 + ApplicationTrapFlag = TRUE;
42987 + zlog_info ("popping ERO...");
42988 + if (RsvpPathPopERO (pRsvpPkt) != E_OK)
42990 + zlog_err ("Cannot pop ERO");
42991 + FreeRsvpPkt (pRsvpPkt);
42992 + return E_ERR;
42994 + zlog_info ("comparing ERO...");
42995 + if (CompareERO (pPsb->OldPacket.ReceivedEro.er,
42996 + pRsvpPkt->ReceivedEro.er, 0) == TRUE)
42998 + zlog_info ("not equal...");
42999 + pPsb->PathRefreshFlag = TRUE;
43001 + zlog_info ("comparing ERO...");
43002 + if (CompareERO (pPsb->OldPacket.ReceivedEro.er,
43003 + pRsvpPkt->ReceivedEro.er, 1) == TRUE)
43005 + zlog_info ("not equal...");
43006 + ApplicationTrapFlag = TRUE;
43008 + if (pPsb->OldPacket.SessionAttributes.CType ==
43009 + SESSION_ATTRIBUTES_RA_CLASS_TYPE)
43011 + if (pPsb->OldPacket.SessionAttributes.u.SessAttrRa.SessionName != NULL)
43013 + XFREE (MTYPE_RSVP,
43014 + pPsb->OldPacket.SessionAttributes.u.SessAttrRa.SessionName);
43015 + pPsb->OldPacket.SessionAttributes.u.SessAttrRa.SessionName = NULL;
43016 + pPsb->OldPacket.SessionAttributes.u.SessAttrRa.NameLength = 0;
43019 + else if (pPsb->OldPacket.SessionAttributes.CType ==
43020 + SESSION_ATTRIBUTES_CLASS_TYPE)
43022 + if (pPsb->OldPacket.SessionAttributes.u.SessAttr.SessionName != NULL)
43024 + XFREE (MTYPE_RSVP,
43025 + pPsb->OldPacket.SessionAttributes.u.SessAttr.SessionName);
43026 + pPsb->OldPacket.SessionAttributes.u.SessAttr.SessionName = NULL;
43027 + pPsb->OldPacket.SessionAttributes.u.SessAttr.NameLength = 0;
43030 + if (pPsb->OldPacket.SessionAttributes.CType !=
43031 + pRsvpPkt->SessionAttributes.CType)
43033 + memcpy (&pPsb->OldPacket.SessionAttributes,
43034 + &pRsvpPkt->SessionAttributes, sizeof (SESSION_ATTRIBUTES_OBJ));
43035 + if (pRsvpPkt->SessionAttributes.CType ==
43036 + SESSION_ATTRIBUTES_RA_CLASS_TYPE)
43038 + pRsvpPkt->SessionAttributes.u.SessAttrRa.SessionName = NULL;
43039 + pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength = 0;
43041 + else if (pRsvpPkt->SessionAttributes.CType ==
43042 + SESSION_ATTRIBUTES_CLASS_TYPE)
43044 + pRsvpPkt->SessionAttributes.u.SessAttr.SessionName = NULL;
43045 + pRsvpPkt->SessionAttributes.u.SessAttr.NameLength = 0;
43047 + ApplicationTrapFlag = TRUE;
43049 + else if (pPsb->OldPacket.SessionAttributes.CType ==
43050 + SESSION_ATTRIBUTES_RA_CLASS_TYPE)
43052 + pPsb->OldPacket.SessionAttributes.u.SessAttrRa.NameLength =
43053 + pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength;
43054 + pPsb->OldPacket.SessionAttributes.u.SessAttrRa.SessionName =
43055 + pRsvpPkt->SessionAttributes.u.SessAttrRa.SessionName;
43056 + pRsvpPkt->SessionAttributes.u.SessAttrRa.SessionName = NULL;
43057 + pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength = 0;
43058 + if ((pPsb->OldPacket.SessionAttributes.u.SessAttrRa.Flags !=
43059 + pRsvpPkt->SessionAttributes.u.SessAttrRa.Flags)
43060 + || (pPsb->OldPacket.SessionAttributes.u.SessAttrRa.SetPrio !=
43061 + pRsvpPkt->SessionAttributes.u.SessAttrRa.SetPrio)
43062 + || (pPsb->OldPacket.SessionAttributes.u.SessAttrRa.HoldPrio !=
43063 + pRsvpPkt->SessionAttributes.u.SessAttrRa.HoldPrio)
43064 + || (pPsb->OldPacket.SessionAttributes.u.SessAttrRa.ExcludeAny !=
43065 + pRsvpPkt->SessionAttributes.u.SessAttrRa.ExcludeAny)
43066 + || (pPsb->OldPacket.SessionAttributes.u.SessAttrRa.IncludeAny !=
43067 + pRsvpPkt->SessionAttributes.u.SessAttrRa.IncludeAny)
43068 + || (pPsb->OldPacket.SessionAttributes.u.SessAttrRa.IncludeAll !=
43069 + pRsvpPkt->SessionAttributes.u.SessAttrRa.IncludeAll))
43071 + pPsb->OldPacket.SessionAttributes.u.SessAttrRa.Flags =
43072 + pRsvpPkt->SessionAttributes.u.SessAttrRa.Flags;
43073 + pPsb->OldPacket.SessionAttributes.u.SessAttrRa.HoldPrio =
43074 + pRsvpPkt->SessionAttributes.u.SessAttrRa.HoldPrio;
43075 + pPsb->OldPacket.SessionAttributes.u.SessAttrRa.SetPrio =
43076 + pRsvpPkt->SessionAttributes.u.SessAttrRa.SetPrio;
43078 + pPsb->OldPacket.SessionAttributes.u.SessAttrRa.ExcludeAny =
43079 + pRsvpPkt->SessionAttributes.u.SessAttrRa.ExcludeAny;
43080 + pPsb->OldPacket.SessionAttributes.u.SessAttrRa.IncludeAny =
43081 + pRsvpPkt->SessionAttributes.u.SessAttrRa.IncludeAny;
43082 + pPsb->OldPacket.SessionAttributes.u.SessAttrRa.IncludeAll =
43083 + pRsvpPkt->SessionAttributes.u.SessAttrRa.IncludeAll;
43084 + ApplicationTrapFlag = TRUE;
43087 + else if (pPsb->OldPacket.SessionAttributes.CType ==
43088 + SESSION_ATTRIBUTES_CLASS_TYPE)
43090 + pPsb->OldPacket.SessionAttributes.u.SessAttr.NameLength =
43091 + pRsvpPkt->SessionAttributes.u.SessAttr.NameLength;
43092 + pPsb->OldPacket.SessionAttributes.u.SessAttr.SessionName =
43093 + pRsvpPkt->SessionAttributes.u.SessAttr.SessionName;
43094 + pRsvpPkt->SessionAttributes.u.SessAttr.SessionName = NULL;
43095 + pRsvpPkt->SessionAttributes.u.SessAttr.NameLength = 0;
43096 + if ((pPsb->OldPacket.SessionAttributes.u.SessAttr.Flags !=
43097 + pRsvpPkt->SessionAttributes.u.SessAttr.Flags)
43098 + || (pPsb->OldPacket.SessionAttributes.u.SessAttr.SetPrio !=
43099 + pRsvpPkt->SessionAttributes.u.SessAttr.SetPrio)
43100 + || (pPsb->OldPacket.SessionAttributes.u.SessAttr.HoldPrio !=
43101 + pRsvpPkt->SessionAttributes.u.SessAttr.HoldPrio))
43103 + pPsb->OldPacket.SessionAttributes.u.SessAttr.Flags =
43104 + pRsvpPkt->SessionAttributes.u.SessAttr.Flags;
43105 + pPsb->OldPacket.SessionAttributes.u.SessAttr.HoldPrio =
43106 + pRsvpPkt->SessionAttributes.u.SessAttr.HoldPrio;
43107 + pPsb->OldPacket.SessionAttributes.u.SessAttr.SetPrio =
43108 + pRsvpPkt->SessionAttributes.u.SessAttr.SetPrio;
43110 + ApplicationTrapFlag = TRUE;
43113 + FreeERO (&pPsb->OldPacket.ReceivedEro);
43114 + pPsb->OldPacket.ReceivedEro = pRsvpPkt->ReceivedEro;
43115 + pRsvpPkt->ReceivedEro.er = NULL;
43116 + FreeRRO (&pPsb->OldPacket.ReceivedRro);
43117 + pPsb->OldPacket.ReceivedRro = pRsvpPkt->ReceivedRro;
43118 + pRsvpPkt->ReceivedRro.rr = NULL;
43119 + if ((ApplicationTrapFlag == TRUE) ||
43120 + ((IsEgress (pPsb) == TRUE) && (pPsb->pRsb == NULL)))
43122 + if (IsEgress (pPsb) == TRUE)
43124 + if (pPsb->OldPacket.ReceivedEro.er != NULL)
43126 + zlog_err ("Reaching Egress with non-empty ERO!!!");
43128 + else
43130 + zlog_info ("Egress reached");
43131 + if (StartPathAgeOutTimer
43132 + (pPsb->AgeOutValue, &pPsb->AgeOutTimer, pPsb) != E_OK)
43134 + zlog_err ("Cannot start AgeOut timer ");
43136 + FreeRsvpPkt (pRsvpPkt);
43137 + return NewModifiedPath (pPsb);
43140 + else
43142 + if (StopPathRefreshTimer (&pPsb->PathRefreshTimer) != E_OK)
43144 + zlog_err ("Cannot stop PathRefresh timer");
43146 + zlog_info ("Locking Flow %s %d", __FILE__, __LINE__);
43147 + pPsb->TE_InProcess = TRUE;
43148 + pPsb->PathRefreshFlag = FALSE;
43149 + PrepareAndSendMsg2TE (pPsb);
43152 + else
43154 + if (StartPathAgeOutTimer (pPsb->AgeOutValue, &pPsb->AgeOutTimer, pPsb)
43155 + != E_OK)
43157 + zlog_err ("Cannot start AgeOut timer ");
43159 + if (pPsb->PathRefreshFlag == TRUE)
43161 + if (pPsb->OutIfIndex != 0)
43163 + if (RsvpPathRefresh (pPsb) != E_OK)
43165 + zlog_err ("an error on PathRefresh %s %d", __FILE__,
43166 + __LINE__);
43167 + FreeRsvpPkt (pRsvpPkt);
43168 + return E_ERR;
43171 + pPsb->PathRefreshFlag = FALSE;
43174 + if (pPsb->ResvRefreshFlag == TRUE)
43176 + zlog_info ("RESV refresh will be called here");
43177 + pPsb->ResvRefreshFlag = FALSE;
43179 + FreeRsvpPkt (pRsvpPkt);
43180 + zlog_info ("leaving ProcessRsvpPathMessage");
43181 + return E_OK;
43184 +E_RC
43185 +ProcessTEMsgUponPath (TE_API_MSG * pMsg)
43187 + PSB_KEY PsbKey;
43188 + PSB *pPsb;
43190 + uns8 FrwChangeFlag = FALSE;
43191 + zlog_info ("entering ProcessTEMsgUponPath");
43192 + memset (&PsbKey, 0, sizeof (PSB_KEY));
43193 + PsbKey = pMsg->u.PathNotification.PsbKey;
43195 + zlog_info ("Session.Dest %x .TunnelId %x .ExtTunnelId %x .Src %x .LspId %x",
43196 + PsbKey.Session.Dest,
43197 + PsbKey.Session.TunnelId,
43198 + PsbKey.Session.ExtTunelId,
43199 + PsbKey.SenderTemplate.IpAddr, PsbKey.SenderTemplate.LspId);
43201 + if ((pPsb = FindPsb (&PsbKey)) != NULL)
43203 + zlog_info ("UnLocking Flow %s %d", __FILE__, __LINE__);
43204 + pPsb->TE_InProcess = FALSE;
43205 + if (pMsg->u.PathNotification.rc != PATH_PROC_OK)
43207 + uns8 ErrCode;
43208 + uns16 ErrVal = 0;
43209 + switch (pMsg->u.PathNotification.rc)
43211 + case BW_UNAVAIL:
43212 + ErrCode = POLICY_CTRL_FAILURE_ERR_CODE;
43213 + break;
43214 + case NO_ROUTE:
43215 + ErrCode = ROUTING_PROBLEM_ERR_CODE;
43216 + if (pPsb->OldPacket.ReceivedEro.er != NULL)
43218 + if (pPsb->OldPacket.ReceivedEro.er->SubObjHdr.LType & 0x80)
43219 + ErrVal = BAD_LOOSE_NODE;
43220 + else
43221 + ErrVal = BAD_STRICT_NODE;
43223 + else
43225 + ErrVal = NO_ROUTE_AVAILABLE;
43227 + break;
43228 + case LABEL_ALLOC_FAILURE:
43229 + ErrCode = ROUTING_PROBLEM_ERR_CODE;
43230 + ErrVal = LABEL_ALLOCATION_FAILURE;
43231 + break;
43232 + case UNSUP_L3PID:
43233 + ErrCode = ROUTING_PROBLEM_ERR_CODE;
43234 + ErrVal = UNSUPPORTED_L3PID;
43235 + break;
43236 + default:
43237 + zlog_err ("Unknown return code, forcing to NO_ROUTE %s %d",
43238 + __FILE__, __LINE__);
43239 + ErrCode = ROUTING_PROBLEM_ERR_CODE;
43240 + ErrVal = NO_ROUTE_AVAILABLE;
43242 + if (GeneratePathErrMessage (pPsb, ErrCode, ErrVal) != E_OK)
43244 + zlog_err ("Cannot generate PathErr message");
43247 + if (DeleteSender (pPsb) != E_OK)
43249 + zlog_err ("An error on DeleteSender %s %d", __FILE__, __LINE__);
43251 + return E_OK;
43253 + pPsb->Label = pMsg->u.PathNotification.Label;
43254 + if (pPsb->NextHop != pMsg->u.PathNotification.NextHop)
43256 + pPsb->NextHop = pMsg->u.PathNotification.NextHop;
43257 + FrwChangeFlag = TRUE;
43259 + if (pPsb->OutIfIndex != pMsg->u.PathNotification.OutIfIndex)
43261 + pPsb->OutIfIndex = pMsg->u.PathNotification.OutIfIndex;
43262 + FrwChangeFlag = TRUE;
43264 + if (FrwChangeFlag == TRUE)
43266 + if (pPsb->OldPacket.ReceivedRro.rr != NULL)
43268 + if (pPsb->OldPacket.AddedRro.rr == NULL)
43270 + if ((pPsb->OldPacket.AddedRro.rr =
43271 + (RR_SUBOBJ *) XMALLOC (MTYPE_RSVP,
43272 + sizeof (RR_SUBOBJ))) == NULL)
43274 + zlog_err ("Cannotallocate memory %s %d", __FILE__,
43275 + __LINE__);
43276 + return E_ERR;
43278 + memset (pPsb->OldPacket.AddedRro.rr, 0, sizeof (RR_SUBOBJ));
43280 + pPsb->OldPacket.AddedRro.rr->SubObjHdr.Type = RRO_SUBTYPE_IPV4;
43281 + pPsb->OldPacket.AddedRro.rr->SubObjHdr.Length = 8;
43282 + if (IpAddrGetByIfIndex
43283 + (pPsb->OutIfIndex,
43284 + &pPsb->OldPacket.AddedRro.rr->u.Ipv4.IpAddr) == E_OK)
43286 + pPsb->OldPacket.AddedRro.rr->u.Ipv4.PrefixLen = 32;
43288 + else
43290 + zlog_err ("Cannot get IP address by IfIndex");
43291 + XFREE (MTYPE_RSVP, pPsb->OldPacket.AddedRro.rr);
43292 + pPsb->OldPacket.AddedRro.rr = NULL;
43295 + pPsb->OldPacket.SentRsvpHop.LIH = pPsb->OutIfIndex;
43296 + if (IpAddrGetByIfIndex
43297 + (pPsb->OutIfIndex, &pPsb->OldPacket.SentRsvpHop.PHop) != E_OK)
43299 + zlog_err ("Cannot get IP address by IfIndex");
43301 + else
43303 + zlog_info ("NHOP %x", pPsb->OldPacket.SentRsvpHop.PHop);
43305 + if (pPsb->pSentBuffer)
43307 + XFREE (MTYPE_RSVP, pPsb->pSentBuffer);
43308 + pPsb->pSentBuffer = NULL;
43309 + pPsb->SentBufferLen = 0;
43311 + pPsb->Label = pMsg->u.PathNotification.Label;
43313 + if (StartPathAgeOutTimer (pPsb->AgeOutValue, &pPsb->AgeOutTimer, pPsb)
43314 + != E_OK)
43316 + zlog_err ("Cannot start AgeOut timer ");
43318 + RsvpPathRefresh (pPsb);
43319 + PsbDequeueAndInvokeMessages (pPsb);
43320 + zlog_info ("leaving ProcessTEMsgUponPath+");
43321 + return E_OK;
43323 + else
43325 + zlog_debug ("cannot find PSB");
43327 + zlog_info ("leaving ProcessTEMsgUponPath-");
43328 + return E_ERR;
43331 +uns16
43332 +ErHopsCount (PSB * pPsb)
43334 + ER_SUBOBJ *pErSubObj = pPsb->OldPacket.ReceivedEro.er;
43335 + uns16 Count = 0;
43336 + while (pErSubObj != NULL)
43338 + if (pErSubObj->SubObjHdr.LType != ERO_SUBTYPE_IPV4)
43340 + break;
43342 + else if (pErSubObj->SubObjHdr.LType & 0x80)
43344 + return (Count + 1);
43346 + Count++;
43347 + pErSubObj = pErSubObj->next;
43349 + return Count;
43352 +static void
43353 +PrepareAndSendMsg2TE (PSB * pPsb)
43355 + TE_API_MSG msg;
43356 + memset (&msg, 0, sizeof (msg));
43357 + msg.NotificationType = PATH_MSG_NOTIFICATION;
43358 + msg.u.PathNotification.PsbKey = pPsb->PsbKey;
43359 + msg.u.PathNotification.BW = pPsb->OldPacket.SenderTSpec.PeakDataRate;
43360 + if (pPsb->OldPacket.SessionAttributes.CType ==
43361 + SESSION_ATTRIBUTES_RA_CLASS_TYPE)
43363 + msg.u.PathNotification.RA_Valid = 1;
43364 + msg.u.PathNotification.ExcludeAny =
43365 + pPsb->OldPacket.SessionAttributes.u.SessAttrRa.ExcludeAny;
43366 + msg.u.PathNotification.IncludeAny =
43367 + pPsb->OldPacket.SessionAttributes.u.SessAttrRa.IncludeAny;
43368 + msg.u.PathNotification.IncludeAll =
43369 + pPsb->OldPacket.SessionAttributes.u.SessAttrRa.IncludeAll;
43370 + msg.u.PathNotification.HoldPrio =
43371 + pPsb->OldPacket.SessionAttributes.u.SessAttrRa.HoldPrio;
43372 + msg.u.PathNotification.SetupPrio =
43373 + pPsb->OldPacket.SessionAttributes.u.SessAttrRa.SetPrio;
43374 + if (pPsb->OldPacket.SessionAttributes.u.SessAttrRa.
43375 + Flags & LOCAL_PROTECTION_DESIRED)
43377 + msg.u.PathNotification.LocalProtection = 1;
43379 + if (pPsb->OldPacket.SessionAttributes.u.SessAttrRa.
43380 + Flags & SE_STYLE_DESIRED)
43382 + msg.u.PathNotification.SharedExplicit = 1;
43385 + else if (pPsb->OldPacket.SessionAttributes.CType ==
43386 + SESSION_ATTRIBUTES_CLASS_TYPE)
43388 + msg.u.PathNotification.HoldPrio =
43389 + pPsb->OldPacket.SessionAttributes.u.SessAttr.HoldPrio;
43390 + msg.u.PathNotification.SetupPrio =
43391 + pPsb->OldPacket.SessionAttributes.u.SessAttr.SetPrio;
43392 + if (pPsb->OldPacket.SessionAttributes.u.SessAttr.
43393 + Flags & LOCAL_PROTECTION_DESIRED)
43395 + msg.u.PathNotification.LocalProtection = 1;
43397 + if (pPsb->OldPacket.SessionAttributes.u.SessAttr.
43398 + Flags & SE_STYLE_DESIRED)
43400 + msg.u.PathNotification.SharedExplicit = 1;
43403 + else
43405 + msg.u.PathNotification.HoldPrio = 4; /* default */
43406 + msg.u.PathNotification.SetupPrio = 4;
43408 + msg.u.PathNotification.ErHopNumber = ErHopsCount (pPsb);
43409 + if (msg.u.PathNotification.ErHopNumber > 0)
43411 + ER_SUBOBJ *pErSubObj = pPsb->OldPacket.ReceivedEro.er;
43412 + int i;
43413 + if (!(pErSubObj->SubObjHdr.LType & 0x80))
43415 + msg.u.PathNotification.FirstErHopStrict = 1;
43417 + for (i = 0; i < msg.u.PathNotification.ErHopNumber;
43418 + i++, pErSubObj = pErSubObj->next)
43420 + msg.u.PathNotification.ErHops[i] = pErSubObj->u.Ipv4.IpAddress;
43423 + rsvp_send_msg (&msg, sizeof (msg));
43426 +E_RC
43427 +DeletePsb (PSB * pPsb)
43429 + if (StopPathAgeOutTimer (&pPsb->AgeOutTimer) != E_OK)
43431 + zlog_err ("Cannot stop Ageout timer");
43432 + return E_ERR;
43434 + if (StopPathRefreshTimer (&pPsb->PathRefreshTimer) != E_OK)
43436 + zlog_err ("Cannot stop PathRefresh timer");
43437 + return E_ERR;
43439 + if (pPsb->InIfIndex != 0)
43441 + PrepareAndSendLabelReleaseMsg2TE (pPsb);
43443 + FreePSB (pPsb);
43444 + return E_OK;
43447 +E_RC
43448 +DeleteSender (PSB * pPsb)
43450 + RSB *pRsb;
43451 + FILTER_LIST *pFilterList, *pFilterListPrev = NULL;
43452 + FILTER_SPEC_DATA *pFilterSpecData = NULL;
43453 + int Shared = 0;
43454 + zlog_info ("entering DeleteSender");
43455 + zlog_info ("Session.Dest %x .TunnelId %x .ExtTunnelId %x .Src %x .LspId %x",
43456 + pPsb->PsbKey.Session.Dest,
43457 + pPsb->PsbKey.Session.TunnelId,
43458 + pPsb->PsbKey.Session.ExtTunelId,
43459 + pPsb->PsbKey.SenderTemplate.IpAddr,
43460 + pPsb->PsbKey.SenderTemplate.LspId);
43461 + zlog_info ("pPsb %x pRsb %x", pPsb, pPsb->pRsb);
43462 + if ((pRsb = pPsb->pRsb) == NULL)
43464 + RSB_KEY RsbKey;
43465 + memset (&RsbKey, 0, sizeof (RSB_KEY));
43466 + RsbKey.Session = pPsb->PsbKey.Session;
43467 + pRsb = FindRsb (&RsbKey);
43469 + if (pRsb != NULL)
43471 + if ((pRsb->OldPacket.Style.OptionVector2 & 0x001F) == SE_STYLE_BITS)
43473 + Shared = 1;
43474 + zlog_info ("Shared %s %d", __FILE__, __LINE__);
43476 + else
43478 + zlog_info ("Not Shared %s %d", __FILE__, __LINE__);
43480 + pFilterList = pRsb->OldPacket.pFilterList;
43481 + zlog_info ("searching for filter data");
43482 + while (pFilterList != NULL)
43484 + if ((pFilterSpecData = pFilterList->pFilterSpecData) != NULL)
43486 + zlog_info ("%x %x %x %x",
43487 + pPsb->PsbKey.SenderTemplate.IpAddr,
43488 + pPsb->PsbKey.SenderTemplate.LspId,
43489 + pFilterSpecData->FilterSpec.IpAddr,
43490 + pFilterSpecData->FilterSpec.LspId);
43491 + if (memcmp (&pPsb->PsbKey.SenderTemplate,
43492 + &pFilterSpecData->FilterSpec,
43493 + sizeof (FILTER_SPEC_OBJ)) == 0)
43495 + if (pFilterListPrev == NULL)
43497 + pRsb->OldPacket.pFilterList =
43498 + pRsb->OldPacket.pFilterList->next;
43500 + else
43502 + pFilterListPrev->next = pFilterList->next;
43504 + if (pPsb->InIfIndex != 0)
43506 + pFilterSpecData->ToBeDeleted = 1;
43507 + if (pFilterSpecData->pPHopResvRefreshList != NULL)
43508 + pFilterSpecData->pPHopResvRefreshList->
43509 + MustBeProcessed = 1;
43511 + XFREE (MTYPE_RSVP, pFilterList);
43512 + break;
43514 + pFilterSpecData = NULL;
43516 + pFilterListPrev = pFilterList;
43517 + pFilterList = pFilterList->next;
43519 + if (ForwardResvTearMsg (pRsb) != E_OK)
43521 + zlog_err ("An error on ForwardResvTearMsg");
43523 + if (FilterShutDown (pFilterSpecData, Shared) != E_OK)
43525 + zlog_err ("An error on FilterShutDown");
43527 + if (ProcessEffectiveFlows (pRsb) != E_OK)
43529 + zlog_err ("an error on ProcessEffectiveFlows %s %d", __FILE__,
43530 + __LINE__);
43532 + if (pRsb->OldPacket.pFilterList != NULL)
43534 + if (ProcessPHopFilterSpecLists (pRsb, Shared) != E_OK)
43536 + zlog_err ("an error on ProcessPHopFilterSpecLists %s %d",
43537 + __FILE__, __LINE__);
43540 + else
43542 + /* delete RSB */
43543 + FreeRSB (pRsb);
43546 + if (DeletePsb (pPsb) != E_OK)
43548 + zlog_info ("Cannot delete PSB %s %d", __FILE__, __LINE__);
43549 + zlog_info ("leaving DeleteSender-");
43550 + return E_ERR;
43552 + zlog_info ("leaving DeleteSender+");
43553 + return E_OK;
43556 +E_RC
43557 +ProcessRsvpPathTearMessage (RSVP_PKT * pRsvpPkt, uns32 IfIndex,
43558 + IPV4_ADDR SrcIpAddr, uns8 ttl)
43560 + PSB *pPsb;
43561 + PSB_KEY PsbKey;
43562 + RSVP_PKT_QUEUE *pQueuedItem;
43563 + zlog_info ("entering ProcessRsvpPathTearMessage");
43565 + RsvpStatistics.PathTearMsgCount++;
43566 + memset (&PsbKey, 0, sizeof (PSB_KEY));
43568 + PsbKey.Session = pRsvpPkt->Session;
43569 + PsbKey.SenderTemplate = pRsvpPkt->SenderTemplate;
43571 + zlog_info ("Session.Dest %x .TunnelId %x .ExtTunnelId %x .Src %x .LspId %x",
43572 + PsbKey.Session.Dest,
43573 + PsbKey.Session.TunnelId,
43574 + PsbKey.Session.ExtTunelId,
43575 + PsbKey.SenderTemplate.IpAddr, PsbKey.SenderTemplate.LspId);
43577 + if ((pPsb = FindPsb (&PsbKey)) == NULL)
43579 + zlog_info ("leaving ProcessRsvpPathTearMessage");
43580 + FreeRsvpPkt (pRsvpPkt);
43581 + return E_OK;
43583 + if (pPsb->OutIfIndex != 0)
43585 + if (EncodeAndSendRsvpPathTearMessage
43586 + (pRsvpPkt, pPsb->NextHop, pPsb->OutIfIndex, pPsb->ttl - 1) != E_OK)
43588 + zlog_err ("An error on EncodeAndSendRsvpPathTearMessage");
43591 + if ((pPsb->TE_InProcess == TRUE) ||
43592 + ((pPsb->pFilterSpecData != NULL) &&
43593 + (pPsb->pFilterSpecData->pEffectiveFlow != NULL) &&
43594 + (pPsb->pFilterSpecData->pEffectiveFlow->TE_InProcess == TRUE)))
43596 + if ((pQueuedItem =
43597 + (RSVP_PKT_QUEUE *) XMALLOC (MTYPE_RSVP,
43598 + sizeof (RSVP_PKT_QUEUE))) == NULL)
43600 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
43602 + pQueuedItem->MsgType = PATH_TEAR_MSG;
43603 + pQueuedItem->InIfIndex = IfIndex;
43604 + pQueuedItem->pRsvpPkt = pRsvpPkt;
43605 + pQueuedItem->SourceIp = SrcIpAddr;
43606 + pQueuedItem->ttl = ttl;
43607 + pQueuedItem->next = NULL;
43608 + if (EnqueueRsvpPacket (pQueuedItem, &pPsb->packet_queue) != E_OK)
43610 + zlog_err ("Cannot enqueue packet %s %d", __FILE__, __LINE__);
43611 + return E_ERR;
43613 + return E_OK;
43615 + FreeRsvpPkt (pRsvpPkt);
43617 + if (DeleteSender (pPsb) != E_OK)
43619 + zlog_err ("an error on DeleteSender");
43621 + return E_OK;
43624 +E_RC
43625 +ProcessRsvpPathErrMessage (RSVP_PKT * pRsvpPkt, uns32 IfIndex,
43626 + IPV4_ADDR SrcIpAddr, uns8 ttl)
43628 + PSB *pPsb;
43629 + PSB_KEY PsbKey;
43631 + zlog_info ("entering ProcessRsvpPathErrMessage");
43632 + RsvpStatistics.PathErrMsgCount++;
43633 + memset (&PsbKey, 0, sizeof (PSB_KEY));
43635 + PsbKey.Session = pRsvpPkt->Session;
43636 + PsbKey.SenderTemplate = pRsvpPkt->SenderTemplate;
43638 + zlog_info ("Session.Dest %x .TunnelId %x .ExtTunnelId %x .Src %x .LspId %x",
43639 + PsbKey.Session.Dest,
43640 + PsbKey.Session.TunnelId,
43641 + PsbKey.Session.ExtTunelId,
43642 + PsbKey.SenderTemplate.IpAddr, PsbKey.SenderTemplate.LspId);
43644 + if ((pPsb = FindPsb (&PsbKey)) == NULL)
43646 + FreeRsvpPkt (pRsvpPkt);
43647 + return E_ERR;
43649 + if (pPsb->InIfIndex == 0)
43651 + zlog_info ("Ingress: PathErr received");
43652 + PrepareAndSendPathErrNotificationMsg2TE (pPsb, &pRsvpPkt->ErrorSpec);
43654 + else
43655 + if (EncodeAndSendRsvpPathErrMessage
43656 + (pRsvpPkt, pPsb->PrevHop, pPsb->InIfIndex, pPsb->ttl - 1) != E_OK)
43658 + zlog_err ("An error in EncodeAndSendRsvpPathErrMessage %s %d", __FILE__,
43659 + __LINE__);
43660 + FreeRsvpPkt (pRsvpPkt);
43661 + return E_ERR;
43663 + FreeRsvpPkt (pRsvpPkt);
43664 + return E_OK;
43667 +static E_RC
43668 +StartPathAgeOutTimer (uns32 time, struct thread **pTimerId, void *data)
43670 + zlog_info ("entering StartPathAgeOutTimer");
43671 + *pTimerId = thread_add_timer (master, RsvpPathAgeOut, data, time);
43672 + THREAD_VAL (*pTimerId) = time;
43673 + zlog_info ("leaving StartPathAgeOutTimer");
43674 + return E_OK;
43677 +static E_RC
43678 +StopPathAgeOutTimer (struct thread **pTimerId)
43680 + zlog_info ("entering StopPathAgeOutTimer");
43681 + thread_cancel (*pTimerId);
43682 + *pTimerId = NULL;
43683 + zlog_info ("leaving StopPathAgeOutTimer");
43684 + return E_OK;
43687 +static E_RC
43688 +StartPathRefreshTimer (uns32 time, struct thread **pTimerId, void *data)
43690 + zlog_info ("entering StartPathRefreshTimer");
43691 + *pTimerId = thread_add_timer (master, RsvpPathRefreshTimer, data, time);
43692 + zlog_info ("leaving StartPathRefreshTimer");
43693 + return E_OK;
43696 +static E_RC
43697 +StopPathRefreshTimer (struct thread **pTimerId)
43699 + zlog_info ("entering StopPathRefreshTimer");
43700 + thread_cancel (*pTimerId);
43701 + *pTimerId = NULL;
43702 + zlog_info ("leaving StopPathRefreshTimer");
43703 + return E_OK;
43706 +static void
43707 +PrepareAndSendLabelReleaseMsg2TE (PSB * pPsb)
43709 + TE_API_MSG msg;
43711 + memset (&msg, 0, sizeof (msg));
43712 + msg.NotificationType = LABEL_RELEASE_NOTIFICATION;
43713 + msg.u.LabelRelease.PsbKey = pPsb->PsbKey;
43714 + msg.u.LabelRelease.Label = pPsb->Label;
43715 + zlog_info ("sending message to TE upon RESV");
43716 + rsvp_send_msg (&msg, sizeof (msg));
43719 +static void
43720 +PrepareAndSendPathErrNotificationMsg2TE (PSB * pPsb,
43721 + ERR_SPEC_OBJ * pErrSpecObj)
43723 + TE_API_MSG msg;
43725 + memset (&msg, 0, sizeof (msg));
43726 + msg.NotificationType = PATH_ERR_NOTIFICATION;
43727 + msg.u.PathErrNotification.PsbKey = pPsb->PsbKey;
43728 + msg.u.PathErrNotification.ErrSpec = *pErrSpecObj;
43729 + zlog_info ("sending message to TE upon RESV");
43730 + rsvp_send_msg (&msg, sizeof (msg));
43733 +E_RC
43734 +GeneratePathErrMessage (PSB * pPsb, uns8 ErrCode, uns16 ErrVal)
43736 + RSVP_PKT RsvpPkt;
43737 + memset (&RsvpPkt, 0, sizeof (RSVP_PKT));
43738 + RsvpPkt.Session = pPsb->PsbKey.Session;
43739 + RsvpPkt.SenderTemplate = pPsb->PsbKey.SenderTemplate;
43740 + RsvpPkt.SenderTSpec = pPsb->OldPacket.SenderTSpec;
43741 + RsvpPkt.ErrorSpec.IpAddr = GetRouterId ();
43742 + RsvpPkt.ErrorSpec.ErrCode = ErrCode;
43743 + RsvpPkt.ErrorSpec.ErrVal = ErrVal;
43744 + if (EncodeAndSendRsvpPathErrMessage
43745 + (&RsvpPkt, pPsb->PrevHop, pPsb->InIfIndex, 255) != E_OK)
43747 + zlog_err ("Cannot encode/send PathErr message %s %d", __FILE__,
43748 + __LINE__);
43749 + return E_ERR;
43751 + return E_OK;
43753 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_psb.h quagga-mpls/rsvpd/rsvp_psb.h
43754 --- quagga/rsvpd/rsvp_psb.h 1969-12-31 18:00:00.000000000 -0600
43755 +++ quagga-mpls/rsvpd/rsvp_psb.h 2007-06-14 21:35:58.000000000 -0500
43756 @@ -0,0 +1,49 @@
43757 +#ifndef __RSVP_PSB__
43758 +#define __RSVP_PSB__
43761 +typedef struct _psb_
43763 + PATRICIA_NODE Node;
43764 + PSB_KEY PsbKey;
43765 + RSVP_PKT OldPacket;
43766 + int InIfIndex;
43767 + IPV4_ADDR PrevHop;
43768 + uns8 ttl;
43769 + int OutIfIndex;
43770 + uns32 Label;
43771 + IPV4_ADDR NextHop;
43772 + uns32 RefreshValue;
43773 + struct thread *PathRefreshTimer;
43774 + uns32 AgeOutValue;
43775 + struct thread *AgeOutTimer;
43776 + uns8 PathRefreshFlag;
43777 + uns8 ResvRefreshFlag;
43778 + uns8 TE_InProcess;
43779 + char *pSentBuffer;
43780 + uns16 SentBufferLen;
43781 + struct _rsb_ *pRsb;
43782 + FILTER_SPEC_DATA *pFilterSpecData;
43783 + struct _rsvp_pkt_queue_ *packet_queue;
43784 +} PSB;
43786 +struct _te_api_msg_;
43788 +E_RC DeleteSender (PSB * pPsb);
43789 +E_RC ProcessRsvpPathMessage (RSVP_PKT * pRsvpPkt, uns32 IfIndex,
43790 + IPV4_ADDR SrcIpAddr, uns8 ttl);
43791 +E_RC ProcessRsvpPathErrMessage (RSVP_PKT * pRsvpPkt, uns32 IfIndex,
43792 + IPV4_ADDR SrcIpAddr, uns8 ttl);
43793 +E_RC ProcessRsvpPathTearMessage (RSVP_PKT * pRsvpPkt, uns32 IfIndex,
43794 + IPV4_ADDR SrcIpAddr, uns8 ttl);
43795 +E_RC GeneratePathErrMessage (PSB * pPsb, uns8 ErrCode, uns16 ErrVal);
43796 +PSB *GetNextPSB (PSB_KEY * pPsbKey);
43797 +PSB *FindPsb (PSB_KEY * pPsbKey);
43798 +PSB *NewPsb (PSB_KEY * pPsbKey);
43799 +E_RC RsvpPathRefresh (PSB * pPsb);
43800 +E_RC InitRsvpPathMessageProcessing ();
43801 +E_RC ProcessTEMsgUponPath (struct _te_api_msg_ *pMsg);
43802 +E_RC RemovePsb (PSB_KEY * pPsbKey);
43803 +E_RC DeletePsb (PSB * pPsb);
43805 +#endif
43806 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_resv.c quagga-mpls/rsvpd/rsvp_resv.c
43807 --- quagga/rsvpd/rsvp_resv.c 1969-12-31 18:00:00.000000000 -0600
43808 +++ quagga-mpls/rsvpd/rsvp_resv.c 2007-07-02 22:50:59.000000000 -0500
43809 @@ -0,0 +1,3630 @@
43810 +/* Module: rsvp_resv.c
43811 + Contains: RSVP RESV, RESV TEAR and RESV ERROR message
43812 + processing functions.
43813 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
43814 + */
43815 +#include "rsvp.h"
43816 +#include "thread.h"
43818 +uns32 ResvRefreshInterval = 30; /* sec */
43819 +uns32 ResvRefreshMultiple = /*3 */ 12;
43821 +extern RSVP_STATISTICS RsvpStatistics;
43822 +extern struct thread_master *master;
43824 +PATRICIA_TREE ResbTree;
43826 +static E_RC ResvRefreshProc (RSB * pRsb,
43827 + PHOP_RESV_REFRESH_LIST * pPHopResvRefreshList);
43828 +static E_RC BuildRRSubObj (FILTER_SPEC_DATA * pFilterSpecData);
43829 +static void PrepareAndSendMsg2TE4SE (RSB * pRsb,
43830 + EFFECTIVE_FLOW * pEffectiveFlow);
43831 +static void PrepareAndSendMsg2TE4FF (RSB * pRsb,
43832 + FILTER_SPEC_DATA * pFilterSpecData);
43833 +static void PrepareAndSendBWReleaseMsg2TE (PSB * pPsb, uns8 Priority,
43834 + uns32 IfIndex, uns8 Shared);
43835 +static void PrepareAndSendResvTearNotificationMsg2TE (RSB * pRsb,
43836 + FILTER_SPEC_OBJ *
43837 + pFilterSpec);
43838 +E_RC StartBlocadeTimer (uns32 time, struct thread **pTimerId, void *data);
43840 +RSB *
43841 +NewRSB (RSB_KEY * pRsbKey)
43843 + RSB *pRsb = NULL;
43844 + if ((pRsb = (RSB *) XMALLOC (MTYPE_RSVP, sizeof (RSB))) != NULL)
43846 + memset (pRsb, 0, sizeof (RSB));
43847 + pRsb->RsbKey = *pRsbKey;
43848 + pRsb->Node.key_info = (uns8 *) & pRsb->RsbKey;
43849 + if (patricia_tree_add (&ResbTree, &pRsb->Node) != E_OK)
43851 + XFREE (MTYPE_RSVP, pRsb);
43852 + return NULL;
43855 + RsvpStatistics.NewRsbCount++;
43856 + return pRsb;
43859 +RSB *
43860 +GetNextRSB (RSB_KEY * pRsbKey)
43862 + return (RSB *) patricia_tree_getnext (&ResbTree, (const uns8 *) pRsbKey);
43865 +RSB *
43866 +FindRsb (RSB_KEY * pRsbKey)
43868 + return (RSB *) patricia_tree_get (&ResbTree, (const uns8 *) pRsbKey);
43871 +E_RC
43872 +RemoveRSB (RSB_KEY * pRsbKey)
43874 + RSB *pRsb = (RSB *) patricia_tree_get (&ResbTree, (const uns8 *) pRsbKey);
43875 + if (pRsb == NULL)
43877 + zlog_err ("RSB is not found in patricia %s %d", __FILE__, __LINE__);
43878 + return E_ERR;
43880 + return patricia_tree_del (&ResbTree, &pRsb->Node);
43883 +E_RC
43884 +GenerateResvErr4SingleFilterSpec (FILTER_SPEC_DATA * pFilterSpecData,
43885 + RSB * pRsb,
43886 + IPV4_ADDR Dest,
43887 + uns32 OutIfIndex,
43888 + uns8 ErrCode, uns16 ErrVal)
43890 + FILTER_LIST *pFilterList;
43891 + RSVP_PKT RsvpPkt;
43893 + memset (&RsvpPkt, 0, sizeof (RSVP_PKT));
43894 + RsvpPkt.Session = pRsb->RsbKey.Session;
43895 + RsvpPkt.Style = pRsb->OldPacket.Style;
43896 + RsvpPkt.ErrorSpec.IpAddr = GetRouterId ();
43897 + RsvpPkt.ErrorSpec.ErrCode = ErrCode;
43898 + RsvpPkt.ErrorSpec.ErrVal = ErrVal;
43899 + RsvpPkt.SentRsvpHop.LIH = OutIfIndex;
43900 + if (IpAddrGetByIfIndex (OutIfIndex, &RsvpPkt.SentRsvpHop.PHop) != E_OK)
43902 + zlog_err ("Cannot get IP address by IfIndex");
43903 + return E_ERR;
43905 + if ((pFilterList =
43906 + (FILTER_LIST *) XMALLOC (MTYPE_RSVP, sizeof (FILTER_LIST))) == NULL)
43908 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
43909 + return E_ERR;
43911 + memset (pFilterList, 0, sizeof (FILTER_LIST));
43912 + pFilterList->pFilterSpecData = pFilterSpecData;
43913 + RsvpPkt.pFilterList = pFilterList;
43914 + if (EncodeAndSendRsvpResvErrMessage (&RsvpPkt, Dest, OutIfIndex, 200) !=
43915 + E_OK)
43917 + zlog_err ("An error on encode/send %s %d", __FILE__, __LINE__);
43918 + XFREE (MTYPE_RSVP, pFilterList);
43919 + return E_ERR;
43921 + XFREE (MTYPE_RSVP, pFilterList);
43922 + return E_OK;
43925 +E_RC
43926 +InitResvProcessing ()
43928 + PATRICIA_PARAMS params;
43929 + memset (&params, 0, sizeof (params));
43931 + params.key_size = sizeof (RSB_KEY);
43933 + if (patricia_tree_init (&ResbTree, &params) != E_OK)
43935 + zlog_err ("Cannot initiate patricia tree %s %d", __FILE__, __LINE__);
43936 + return E_ERR;
43938 + return E_OK;
43941 +PHOP_RESV_REFRESH_LIST *
43942 +GetOrCreatePHopResvRefreshNode (RSB * pRsb,
43943 + IPV4_ADDR IpAddr, uns32 LIH, uns32 InIfIndex)
43945 + PHOP_RESV_REFRESH_LIST *pPHopResvRefreshList =
43946 + pRsb->pPHopResvRefreshList, *pPHopResvRefreshListPrev =
43947 + NULL, *pPHopResvRefreshListNew;
43949 + while (pPHopResvRefreshList != NULL)
43951 + if ((pPHopResvRefreshList->PHop.PHop == IpAddr) &&
43952 + (pPHopResvRefreshList->PHop.LIH == LIH))
43954 + return pPHopResvRefreshList;
43956 + pPHopResvRefreshListPrev = pPHopResvRefreshList;
43957 + pPHopResvRefreshList = pPHopResvRefreshList->next;
43959 + if ((pPHopResvRefreshListNew =
43960 + (PHOP_RESV_REFRESH_LIST *) XMALLOC (MTYPE_RSVP,
43961 + sizeof (PHOP_RESV_REFRESH_LIST)))
43962 + == NULL)
43964 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
43965 + return NULL;
43967 + memset (pPHopResvRefreshListNew, 0, sizeof (PHOP_RESV_REFRESH_LIST));
43968 + pPHopResvRefreshListNew->PHop.PHop = IpAddr;
43969 + pPHopResvRefreshListNew->PHop.LIH = LIH;
43970 + pPHopResvRefreshListNew->InIfIndex = InIfIndex;
43971 + pPHopResvRefreshListNew->RefreshValue =
43972 + ResvRefreshInterval + RefreshRandomize (ResvRefreshInterval);
43973 + if (pPHopResvRefreshListPrev == NULL)
43975 + pRsb->pPHopResvRefreshList = pPHopResvRefreshListNew;
43977 + else
43979 + pPHopResvRefreshListPrev->next = pPHopResvRefreshListNew;
43980 + pPHopResvRefreshListNew->next = pPHopResvRefreshList;
43982 + return pPHopResvRefreshListNew;
43985 +E_RC
43986 +DeletePHopResvRefreshList (RSB * pRsb,
43987 + PHOP_RESV_REFRESH_LIST * pPHopResvRefreshList)
43989 + PHOP_RESV_REFRESH_LIST *pPHopResvRefreshList2 =
43990 + pRsb->pPHopResvRefreshList, *pPHopResvRefreshListPrev = NULL;
43991 + zlog_info ("entering DeletePHopResvRefreshList");
43992 + while (pPHopResvRefreshList2 != NULL)
43994 + if (pPHopResvRefreshList2 == pPHopResvRefreshList)
43996 + if (pPHopResvRefreshListPrev == NULL)
43998 + pRsb->pPHopResvRefreshList = pRsb->pPHopResvRefreshList->next;
44000 + else
44002 + pPHopResvRefreshListPrev->next = pPHopResvRefreshList2->next;
44004 + if (pPHopResvRefreshList2->pAddedRro)
44005 + XFREE (MTYPE_RSVP, pPHopResvRefreshList2->pAddedRro);
44006 + if (pPHopResvRefreshList2->pSentBuffer)
44007 + XFREE (MTYPE_RSVP, pPHopResvRefreshList2->pSentBuffer);
44008 + XFREE (MTYPE_RSVP, pPHopResvRefreshList2);
44009 + zlog_info ("leaving DeletePHopResvRefreshList+");
44010 + return E_OK;
44012 + pPHopResvRefreshListPrev = pPHopResvRefreshList2;
44013 + pPHopResvRefreshList2 = pPHopResvRefreshList2->next;
44015 + zlog_info ("leaving DeletePHopResvRefreshList-");
44016 + return E_ERR;
44019 +EFFECTIVE_FLOW *
44020 +GetOrCreateEffectiveFlow (RSB * pRsb, uns32 IfIndex)
44022 + EFFECTIVE_FLOW *pEffectiveFlow, *pEffectiveFlowPrev = NULL;
44023 + zlog_info ("entering GetOrCreateEffectiveFlow");
44024 + pEffectiveFlow = pRsb->pEffectiveFlow;
44025 + while (pEffectiveFlow != NULL)
44027 + if (pEffectiveFlow->IfIndex == IfIndex)
44029 + break;
44031 + pEffectiveFlow = pEffectiveFlow->next;
44033 + if (pEffectiveFlow != NULL)
44035 + zlog_info ("leaving GetOrCreateEffectiveFlow(1)");
44036 + return pEffectiveFlow;
44038 + if ((pEffectiveFlow =
44039 + (EFFECTIVE_FLOW *) XMALLOC (MTYPE_RSVP,
44040 + sizeof (EFFECTIVE_FLOW))) == NULL)
44042 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
44043 + return NULL;
44045 + memset (pEffectiveFlow, 0, sizeof (EFFECTIVE_FLOW));
44046 + pEffectiveFlow->IfIndex = IfIndex;
44047 +// pEffectiveFlow->MustBeProcessed = 1;
44048 + if (pEffectiveFlowPrev == NULL)
44050 + pRsb->pEffectiveFlow = pEffectiveFlow;
44052 + else
44054 + pEffectiveFlowPrev->next = pEffectiveFlow;
44056 + zlog_info ("leaving GetOrCreateEffectiveFlow(2)");
44057 + return pEffectiveFlow;
44060 +E_RC
44061 +DeleteEffectiveFlow (RSB * pRsb, EFFECTIVE_FLOW * pEffectiveFlow)
44063 + EFFECTIVE_FLOW *pEffectiveFlow2 =
44064 + pRsb->pEffectiveFlow, *pEffectiveFlowPrev = NULL;
44065 + zlog_info ("entering DeleteEffectiveFlow");
44066 + while (pEffectiveFlow2 != NULL)
44068 + if (pEffectiveFlow2 == pEffectiveFlow)
44070 + if (pEffectiveFlowPrev == NULL)
44072 + pRsb->pEffectiveFlow = pRsb->pEffectiveFlow->next;
44074 + else
44076 + pEffectiveFlowPrev->next = pEffectiveFlow2->next;
44078 + XFREE (MTYPE_RSVP, pEffectiveFlow2);
44079 + zlog_info ("leaving DeleteEffectiveFlow+");
44080 + return E_OK;
44082 + pEffectiveFlowPrev = pEffectiveFlow2;
44083 + pEffectiveFlow2 = pEffectiveFlow2->next;
44085 + zlog_info ("leaving DeleteEffectiveFlow-");
44086 + return E_ERR;
44089 +E_RC
44090 +DeleteFilterListNode (FILTER_LIST ** ppFilterList,
44091 + FILTER_SPEC_DATA * pFilterSpecData)
44093 + FILTER_LIST *pFilterList, *pFilterListPrev = NULL;
44094 + zlog_info ("entering DeleteFilterListNode");
44095 + if (ppFilterList == NULL)
44097 + return E_OK;
44099 + pFilterList = *ppFilterList;
44100 + while (pFilterList != NULL)
44102 + if (pFilterList->pFilterSpecData == pFilterSpecData)
44104 + break;
44106 + pFilterListPrev = pFilterList;
44107 + pFilterList = pFilterList->next;
44109 + if (pFilterList == NULL)
44111 + return E_ERR;
44113 + if (pFilterListPrev == NULL)
44115 + *ppFilterList = (*ppFilterList)->next;
44117 + else
44119 + pFilterListPrev->next = pFilterList->next;
44121 + XFREE (MTYPE_RSVP, pFilterList);
44122 + zlog_info ("leaving DeleteFilterListNode");
44123 + return E_OK;
44126 +E_RC
44127 +NewFilterListNode (FILTER_LIST ** ppFilterListHead,
44128 + FILTER_SPEC_DATA * pFilterSpecData)
44130 + FILTER_LIST *pFilterList = *ppFilterListHead, *pFilterListPrev = NULL;
44131 + zlog_info ("entering NewFilterListNode");
44132 + while (pFilterList != NULL)
44134 + if (pFilterList->pFilterSpecData == pFilterSpecData)
44136 + zlog_err ("Node already exists %s %d", __FILE__, __LINE__);
44137 + return E_ERR;
44139 + pFilterListPrev = pFilterList;
44140 + pFilterList = pFilterList->next;
44142 + if ((pFilterList =
44143 + (FILTER_LIST *) XMALLOC (MTYPE_RSVP, sizeof (FILTER_LIST))) == NULL)
44145 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
44146 + return E_ERR;
44148 + memset (pFilterList, 0, sizeof (FILTER_LIST));
44149 + pFilterList->pFilterSpecData = pFilterSpecData;
44150 + if (pFilterListPrev == NULL)
44152 + *ppFilterListHead = pFilterList;
44154 + else
44156 + pFilterListPrev->next = pFilterList;
44158 + zlog_info ("leaving NewFilterListNode");
44159 + return E_OK;
44163 +uns8
44164 +AdSpecBWGreaterThanTSpecBW (PSB * pPsb)
44166 + if (pPsb->OldPacket.SentAdSpec.CType != 0)
44168 + if (pPsb->OldPacket.SentAdSpec.AdSpecGen.PathBW >
44169 + pPsb->OldPacket.SenderTSpec.PeakDataRate)
44171 + return TRUE;
44174 + return FALSE;
44177 +uns8
44178 +TSpecGreaterThanFlowSpecGuar (SENDER_TSPEC_OBJ * pSenderTSpec,
44179 + FLOW_SPEC_OBJ * pFlowSpec)
44181 + if (pSenderTSpec->PeakDataRate > pFlowSpec->u.Guar.CtrlLoad.PeakDataRate)
44183 + return TRUE;
44185 + return FALSE;
44188 +uns8
44189 +TSpecGreaterThanFlowSpecCtrl (SENDER_TSPEC_OBJ * pSenderTSpec,
44190 + FLOW_SPEC_OBJ * pFlowSpec)
44192 + if (pSenderTSpec->PeakDataRate > pFlowSpec->u.CtrlLoad.PeakDataRate)
44194 + return TRUE;
44196 + return FALSE;
44199 +uns8
44200 +FlowSpec1GreaterThanFlowSpec2 (FLOW_SPEC_OBJ * pFlowSpec1,
44201 + FLOW_SPEC_OBJ * pFlowSpec2)
44203 + if (pFlowSpec1->ServHdr.ServHdr == FLOW_SPEC_CTRL_LOAD_SERV_NUMBER)
44205 + if (pFlowSpec1->u.CtrlLoad.PeakDataRate >
44206 + pFlowSpec2->u.CtrlLoad.PeakDataRate)
44208 + return TRUE;
44211 + else if (pFlowSpec1->ServHdr.ServHdr == FLOW_SPEC_GUAR_SERV_NUMBER)
44213 + if (pFlowSpec1->u.Guar.CtrlLoad.PeakDataRate >
44214 + pFlowSpec2->u.Guar.CtrlLoad.PeakDataRate)
44216 + return TRUE;
44219 + return FALSE;
44222 +void
44223 +ComposeFlowSpec (PSB * pPsb, FLOW_SPEC_OBJ * pFilterFlowSpec)
44225 + pFilterFlowSpec->MsgHdr.VersionResvd = FLOW_SPEC_MSG_FORMAT;
44226 + pFilterFlowSpec->MsgHdr.MessageLength = FLOW_SPEC_MSG_LENGTH;
44227 + pFilterFlowSpec->ServHdr.ServHdr = FLOW_SPEC_CTRL_LOAD_SERV_NUMBER; /* temp */
44228 + pFilterFlowSpec->ServHdr.Resvd = 0;
44229 + pFilterFlowSpec->ServHdr.ServLength = FLOW_SPEC_DATA_LENGTH;
44230 + pFilterFlowSpec->ParamHdr.ParamID = FLOW_SPEC_TOCKEN_BUCKET_PARAM_ID;
44231 + pFilterFlowSpec->ParamHdr.ParamFlags = 0;
44232 + pFilterFlowSpec->ParamHdr.ParamLength =
44233 + FLOW_SPEC_TOCKEN_BUCKET_PARAM_LENGTH;
44234 + pFilterFlowSpec->u.CtrlLoad.TockenBucketRate =
44235 + pPsb->OldPacket.SenderTSpec.TockenBucketRate;
44236 + pFilterFlowSpec->u.CtrlLoad.TockenBucketSize =
44237 + pPsb->OldPacket.SenderTSpec.TockenBucketSize;
44238 + pFilterFlowSpec->u.CtrlLoad.PeakDataRate =
44239 + pPsb->OldPacket.SenderTSpec.PeakDataRate;
44240 + pFilterFlowSpec->u.CtrlLoad.MinPolicedUnit =
44241 + pPsb->OldPacket.SenderTSpec.MinPolicedUnit;
44242 + pFilterFlowSpec->u.CtrlLoad.MaxPacketSize =
44243 + pPsb->OldPacket.SenderTSpec.MaxPacketSize;
44246 +void
44247 +CheckAndSetFlowSpecObj (PSB * pPsb, FLOW_SPEC_OBJ * pFilterFlowSpec,
44248 + FLOW_SPEC_OBJ * pEffectiveFlowSpec)
44250 + uns8 TSpecSelected = FALSE;
44252 + if (pFilterFlowSpec->ServHdr.ServHdr == FLOW_SPEC_CTRL_LOAD_SERV_NUMBER)
44254 + if (TSpecGreaterThanFlowSpecCtrl
44255 + (&pPsb->OldPacket.SenderTSpec, pFilterFlowSpec) == FALSE)
44257 + TSpecSelected = TRUE;
44260 + else if (pFilterFlowSpec->ServHdr.ServHdr == FLOW_SPEC_GUAR_SERV_NUMBER)
44262 + if (TSpecGreaterThanFlowSpecGuar
44263 + (&pPsb->OldPacket.SenderTSpec, pFilterFlowSpec) == FALSE)
44265 + TSpecSelected = TRUE;
44268 + if (pEffectiveFlowSpec->ServHdr.ServHdr == 0)
44270 + pEffectiveFlowSpec->MsgHdr.VersionResvd = FLOW_SPEC_MSG_FORMAT;
44271 + pEffectiveFlowSpec->MsgHdr.MessageLength = FLOW_SPEC_MSG_LENGTH;
44272 + pEffectiveFlowSpec->ServHdr.ServHdr = pFilterFlowSpec->ServHdr.ServHdr; /* temp */
44273 + pEffectiveFlowSpec->ServHdr.Resvd = 0;
44274 + pEffectiveFlowSpec->ServHdr.ServLength = FLOW_SPEC_DATA_LENGTH;
44275 + pEffectiveFlowSpec->ParamHdr.ParamID = FLOW_SPEC_TOCKEN_BUCKET_PARAM_ID;
44276 + pEffectiveFlowSpec->ParamHdr.ParamFlags = 0;
44277 + pEffectiveFlowSpec->ParamHdr.ParamLength =
44278 + FLOW_SPEC_TOCKEN_BUCKET_PARAM_LENGTH;
44280 + if (TSpecSelected)
44282 + if (pEffectiveFlowSpec->ServHdr.ServHdr ==
44283 + FLOW_SPEC_CTRL_LOAD_SERV_NUMBER)
44285 + if (TSpecGreaterThanFlowSpecCtrl
44286 + (&pPsb->OldPacket.SenderTSpec, pEffectiveFlowSpec) == TRUE)
44288 + pEffectiveFlowSpec->u.CtrlLoad.MaxPacketSize =
44289 + pPsb->OldPacket.SenderTSpec.MaxPacketSize;
44290 + pEffectiveFlowSpec->u.CtrlLoad.MinPolicedUnit =
44291 + pPsb->OldPacket.SenderTSpec.MinPolicedUnit;
44292 + pEffectiveFlowSpec->u.CtrlLoad.PeakDataRate =
44293 + pPsb->OldPacket.SenderTSpec.PeakDataRate;
44294 + pEffectiveFlowSpec->u.CtrlLoad.TockenBucketRate =
44295 + pPsb->OldPacket.SenderTSpec.TockenBucketRate;
44296 + pEffectiveFlowSpec->u.CtrlLoad.TockenBucketSize =
44297 + pPsb->OldPacket.SenderTSpec.TockenBucketSize;
44300 + else if (pEffectiveFlowSpec->ServHdr.ServHdr ==
44301 + FLOW_SPEC_GUAR_SERV_NUMBER)
44303 + if (TSpecGreaterThanFlowSpecGuar
44304 + (&pPsb->OldPacket.SenderTSpec, pEffectiveFlowSpec) == TRUE)
44306 + pEffectiveFlowSpec->u.Guar.CtrlLoad.MaxPacketSize =
44307 + pPsb->OldPacket.SenderTSpec.MaxPacketSize;
44308 + pEffectiveFlowSpec->u.Guar.CtrlLoad.MinPolicedUnit =
44309 + pPsb->OldPacket.SenderTSpec.MinPolicedUnit;
44310 + pEffectiveFlowSpec->u.Guar.CtrlLoad.PeakDataRate =
44311 + pPsb->OldPacket.SenderTSpec.PeakDataRate;
44312 + pEffectiveFlowSpec->u.Guar.CtrlLoad.TockenBucketRate =
44313 + pPsb->OldPacket.SenderTSpec.TockenBucketRate;
44314 + pEffectiveFlowSpec->u.Guar.CtrlLoad.TockenBucketSize =
44315 + pPsb->OldPacket.SenderTSpec.TockenBucketSize;
44319 + else
44321 + if (FlowSpec1GreaterThanFlowSpec2 (pEffectiveFlowSpec, pFilterFlowSpec)
44322 + == FALSE)
44324 + *pEffectiveFlowSpec = *pFilterFlowSpec;
44329 +static int
44330 +BlocadeTimerExpiry (struct thread *thread)
44332 + FILTER_SPEC_DATA *pFilterSpecData = THREAD_ARG (thread);
44333 + memset (&pFilterSpecData->BlocadeTimer, 0, sizeof (struct thread *));
44334 + pFilterSpecData->Blocked = FALSE;
44335 + if ((pFilterSpecData->pPsb->pRsb->OldPacket.Style.OptionVector2 & 0x001F) ==
44336 + SE_STYLE_BITS)
44338 + if (ProcessEffectiveFlows (pFilterSpecData->pPsb->pRsb) != E_OK)
44340 + zlog_err ("An error on ProcessEffectiveFlows");
44343 + else
44345 + if (pFilterSpecData->pPsb->TE_InProcess == TRUE)
44347 + if (StartBlocadeTimer
44348 + (1, &pFilterSpecData->BlocadeTimer, pFilterSpecData) != E_OK)
44350 + zlog_info ("Cannot run Blocade Timer %s %d", __FILE__,
44351 + __LINE__);
44353 + return;
44355 + zlog_info ("Locking Flow %x %x %x %x %x %s %d",
44356 + pFilterSpecData->pPsb->pRsb->RsbKey.Session.Dest,
44357 + pFilterSpecData->pPsb->pRsb->RsbKey.Session.TunnelId,
44358 + pFilterSpecData->pPsb->pRsb->RsbKey.Session.ExtTunelId,
44359 + pFilterSpecData->FilterSpec.IpAddr,
44360 + pFilterSpecData->FilterSpec.LspId, __FILE__, __LINE__);
44361 + pFilterSpecData->pPsb->TE_InProcess = TRUE;
44362 + PrepareAndSendMsg2TE4FF (pFilterSpecData->pPsb->pRsb, pFilterSpecData);
44366 +static int
44367 +FilterAgeOut (struct thread *thread)
44369 + FILTER_SPEC_DATA *pFilterSpecData = THREAD_ARG (thread);
44370 + RSB *pRsb;
44371 + PSB *pPsb;
44372 + uns8 Shared = 0;
44374 + zlog_info ("entering FilterAgeOut");
44375 + if (pFilterSpecData == NULL)
44377 + zlog_err ("pFilterSpecData == NULL %s %d", __FILE__, __LINE__);
44378 + return;
44380 + memset (&pFilterSpecData->AgeOutTimer, 0, sizeof (struct thread *));
44381 + if (pFilterSpecData->pPsb == NULL)
44383 + zlog_err ("pFilterSpecData->pPsb == NULL %s %d", __FILE__, __LINE__);
44384 + return;
44386 + if ((pRsb = pFilterSpecData->pPsb->pRsb) == NULL)
44388 + zlog_err ("pFilterSpecData->pPsb->pRsb == NULL %s %d", __FILE__,
44389 + __LINE__);
44390 + return;
44392 + zlog_info ("Session.Dest %x .TunnelId %x .ExtTunnelId %x Src %x LspId %x",
44393 + pFilterSpecData->pPsb->pRsb->RsbKey.Session.Dest,
44394 + pFilterSpecData->pPsb->pRsb->RsbKey.Session.TunnelId,
44395 + pFilterSpecData->pPsb->pRsb->RsbKey.Session.ExtTunelId,
44396 + pFilterSpecData->FilterSpec.IpAddr,
44397 + pFilterSpecData->FilterSpec.LspId);
44398 + if ((pRsb->OldPacket.Style.OptionVector2 & 0x001F) == SE_STYLE_BITS)
44400 + Shared = 1;
44402 + if (DeleteFilterListNode (&pRsb->OldPacket.pFilterList, pFilterSpecData) !=
44403 + E_OK)
44405 + zlog_err ("Cannot delete filter from RSB's filter list %s %d", __FILE__,
44406 + __LINE__);
44407 + return;
44409 + pPsb = pFilterSpecData->pPsb;
44410 + if (FilterShutDown (pFilterSpecData, Shared) != E_OK)
44412 + zlog_err ("An error in FilterShutDown %s %d", __FILE__, __LINE__);
44413 + return;
44415 + if (pRsb->OldPacket.pFilterList != NULL)
44417 + if (Shared)
44419 + if (ProcessEffectiveFlows (pRsb) != E_OK)
44421 + zlog_err ("An error in ProcessEffectiveFlows %s %d", __FILE__,
44422 + __LINE__);
44425 + /* update TE (BW release) */
44426 + if (ProcessPHopFilterSpecLists (pRsb, Shared) != E_OK)
44428 + zlog_err ("An error in ProcessPHopFilterSpecLists %s %d", __FILE__,
44429 + __LINE__);
44432 + else
44434 + FreeRSB (pRsb);
44436 + RsvpStatistics.FilterAgeOutCount++;
44437 + zlog_info ("leaving FilterAgeOut");
44440 +static int
44441 +PHopResvRefreshTimeOut (struct thread *thread)
44443 + PHOP_RESV_REFRESH_LIST *pPhopResvRefreshList = THREAD_ARG (thread);
44444 + FILTER_LIST *pFilterList;
44445 + FILTER_SPEC_DATA *pFilterSpecData;
44446 + RSB *pRsb;
44447 + zlog_info ("entering PHopResvRefreshTimeOut");
44448 + if (pPhopResvRefreshList == NULL)
44450 + zlog_err ("pPhopResvRefreshList == NULL %s %d", __FILE__, __LINE__);
44451 + zlog_info ("leaving PHopResvRefreshTimeOut-");
44452 + return;
44454 + pFilterList = pPhopResvRefreshList->pFilterList;
44455 + memset (&pPhopResvRefreshList->ResvRefreshTimer, 0,
44456 + sizeof (struct thread *));
44457 + if (pFilterList == NULL)
44459 + zlog_err ("pFilterList == NULL!!! %s %d", __FILE__, __LINE__);
44460 + return;
44462 + if ((pFilterSpecData = pFilterList->pFilterSpecData) == NULL)
44464 + zlog_err ("pFilterSpecData == NULL!!! %s %d", __FILE__, __LINE__);
44465 + return;
44467 + if (pFilterSpecData->pPsb == NULL)
44469 + zlog_err ("pFilterSpecData->pPsb == NULL!!! %s %d", __FILE__, __LINE__);
44470 + return;
44472 + if ((pRsb = pFilterSpecData->pPsb->pRsb) == NULL)
44474 + zlog_err ("pFilterSpecData->pPsb->pRsb == NULL!!! %s %d", __FILE__,
44475 + __LINE__);
44476 + return;
44478 + if (ResvRefreshProc (pRsb, pPhopResvRefreshList) != E_OK)
44480 + zlog_err ("An error on ResvRefreshProc %s %d", __FILE__, __LINE__);
44482 + zlog_info ("leaving PHopResvRefreshTimeOut+");
44485 +E_RC
44486 +StartPHopResvRefreshTimer (uns32 time, struct thread **pTimerId, void *data)
44488 + zlog_info ("entering StartPHopResvRefreshTimer");
44489 + *pTimerId = thread_add_timer (master, PHopResvRefreshTimeOut, data, time);
44490 + zlog_info ("leaving StartPHopResvRefreshTimer");
44491 + return E_OK;
44494 +E_RC
44495 +StopPHopResvRefreshTimer (struct thread * *pTimerId)
44497 + zlog_info ("entering StopPHopResvRefreshTimer");
44498 + thread_cancel (*pTimerId);
44499 + *pTimerId = NULL;
44500 + zlog_info ("leaving StopPHopResvRefreshTimer");
44501 + return E_OK;
44504 +E_RC
44505 +StartFilterAgeOutTimer (uns32 time, struct thread * *pTimerId, void *data)
44507 + zlog_info ("entering StartFilterAgeOutTimer");
44508 + *pTimerId = thread_add_timer (master, FilterAgeOut, data, time);
44509 + zlog_info ("leaving StartFilterAgeOutTimer");
44510 + return E_OK;
44513 +E_RC
44514 +StopFilterAgeOutTimer (struct thread * *pTimerId)
44516 + zlog_info ("entering StopFilterAgeOutTimer");
44517 + thread_cancel (*pTimerId);
44518 + *pTimerId = NULL;
44519 + zlog_info ("leaving StopFilterAgeOutTimer");
44520 + return E_OK;
44523 +E_RC
44524 +StartBlocadeTimer (uns32 time, struct thread * *pTimerId, void *data)
44526 + zlog_info ("entering StartBlocadeTimer");
44527 + *pTimerId = thread_add_timer (master, BlocadeTimerExpiry, data, time);
44528 + zlog_info ("leaving StartBlocadeTimer");
44529 + return E_OK;
44532 +E_RC
44533 +StopBlocadeTimer (struct thread * *pTimerId)
44535 + zlog_info ("entering StopBlocadeTimer");
44536 + thread_cancel (*pTimerId);
44537 + *pTimerId = NULL;
44538 + zlog_info ("leaving StopBlocadeTimer");
44539 + return E_OK;
44542 +static E_RC
44543 +ResvRefreshProc (RSB * pRsb, PHOP_RESV_REFRESH_LIST * pPHopResvRefreshList)
44545 + RSVP_PKT RsvpPkt;
44546 + zlog_info ("entering ResvRefreshProc");
44547 + zlog_info ("Session.Dest %x .TunnelId %x .ExtTunnelId %x",
44548 + pRsb->RsbKey.Session.Dest,
44549 + pRsb->RsbKey.Session.TunnelId, pRsb->RsbKey.Session.ExtTunelId);
44550 + if (pPHopResvRefreshList == NULL)
44552 + zlog_err ("ResvRefreshProc: pPHopResvRefreshList is NULL");
44553 + return E_ERR;
44555 + if ((pPHopResvRefreshList->pSentBuffer == NULL) ||
44556 + (pPHopResvRefreshList->SentBufferLen == 0))
44558 + memset (&RsvpPkt, 0, sizeof (RSVP_PKT));
44559 + RsvpPkt.Session = pRsb->RsbKey.Session;
44560 + RsvpPkt.TimeValues.TimeValues = ResvRefreshInterval * 1000;
44561 + RsvpPkt.SentRsvpHop.LIH = pPHopResvRefreshList->PHop.LIH;
44562 + RsvpPkt.Style = pRsb->OldPacket.Style;
44563 + RsvpPkt.pFilterList = pPHopResvRefreshList->pFilterList;
44565 + if (IpAddrGetByIfIndex
44566 + (pPHopResvRefreshList->InIfIndex,
44567 + &RsvpPkt.SentRsvpHop.PHop) != E_OK)
44569 + zlog_err ("Cannot set RSVP HOP %s %d", __FILE__, __LINE__);
44570 + return E_ERR;
44573 + RsvpPkt.AddedRro.rr = pPHopResvRefreshList->pAddedRro;
44575 + if (EncodeAndSendRsvpResvMessage (&RsvpPkt,
44576 + ntohl (pPHopResvRefreshList->PHop.
44577 + PHop),
44578 + pPHopResvRefreshList->InIfIndex, 255,
44579 + &pPHopResvRefreshList->pSentBuffer,
44580 + &pPHopResvRefreshList->
44581 + SentBufferLen) != E_OK)
44583 + zlog_err ("Cannot encode or send RESV message");
44584 + return E_ERR;
44587 + else
44589 + if (SendRawData (pPHopResvRefreshList->pSentBuffer,
44590 + pPHopResvRefreshList->SentBufferLen,
44591 + ntohl (pPHopResvRefreshList->PHop.PHop),
44592 + pPHopResvRefreshList->pFilterList->pFilterSpecData->
44593 + pPsb->InIfIndex, 2, FALSE) != E_OK)
44595 + zlog_err ("Cannot send raw data %s %d", __FILE__, __LINE__);
44596 + return E_ERR;
44599 + if (StopPHopResvRefreshTimer (&pPHopResvRefreshList->ResvRefreshTimer) !=
44600 + E_OK)
44602 + zlog_err ("Cannot stop PHopResvRefreshTimer %s %d", __FILE__, __LINE__);
44603 + return E_ERR;
44606 + if (StartPHopResvRefreshTimer (pPHopResvRefreshList->RefreshValue,
44607 + &pPHopResvRefreshList->ResvRefreshTimer,
44608 + pPHopResvRefreshList) != E_OK)
44610 + zlog_err ("Cannot start timer %s %d", __FILE__, __LINE__);
44611 + return E_ERR;
44613 + zlog_info ("leaving ResvRefreshProc");
44614 + return E_OK;
44618 +E_RC
44619 +LinkFilter2PHopList (FILTER_SPEC_DATA * pFilterSpecData)
44621 + PSB *pPsb;
44622 + RSB *pRsb;
44623 + uns8 AddRro = FALSE;
44625 + pPsb = pFilterSpecData->pPsb;
44626 + pRsb = pPsb->pRsb;
44628 + if (((pFilterSpecData->pPHopResvRefreshList != NULL) &&
44629 + (!((pFilterSpecData->pPHopResvRefreshList->PHop.PHop ==
44630 + pPsb->OldPacket.ReceivedRsvpHop.PHop)
44631 + && (pFilterSpecData->pPHopResvRefreshList->PHop.LIH ==
44632 + pPsb->OldPacket.ReceivedRsvpHop.LIH))))
44633 + || (pFilterSpecData->pPHopResvRefreshList == NULL))
44635 + if (pFilterSpecData->pPHopResvRefreshList != NULL)
44637 + if (DeleteFilterListNode
44638 + (&pFilterSpecData->pPHopResvRefreshList->pFilterList,
44639 + pFilterSpecData) != E_OK)
44641 + zlog_err ("Cannot delete filter list node %s %d", __FILE__,
44642 + __LINE__);
44643 + return E_ERR;
44645 + pFilterSpecData->pPHopResvRefreshList->MustBeProcessed = 1;
44646 + if (pFilterSpecData->pPHopResvRefreshList->pSentBuffer != NULL)
44648 + XFREE (MTYPE_RSVP,
44649 + pFilterSpecData->pPHopResvRefreshList->pSentBuffer);
44650 + pFilterSpecData->pPHopResvRefreshList->pSentBuffer = NULL;
44651 + pFilterSpecData->pPHopResvRefreshList->SentBufferLen = 0;
44654 + if ((pFilterSpecData->pPHopResvRefreshList =
44655 + GetOrCreatePHopResvRefreshNode (pRsb,
44656 + pPsb->OldPacket.ReceivedRsvpHop.
44657 + PHop,
44658 + pPsb->OldPacket.ReceivedRsvpHop.
44659 + LIH, pPsb->InIfIndex)) == NULL)
44661 + zlog_err ("Cannot create or get PHOP RESV refresh node");
44662 + return E_ERR;
44664 + pFilterSpecData->pPHopResvRefreshList->MustBeProcessed = 1;
44665 + if (pFilterSpecData->pPHopResvRefreshList->pSentBuffer != NULL)
44667 + XFREE (MTYPE_RSVP,
44668 + pFilterSpecData->pPHopResvRefreshList->pSentBuffer);
44669 + pFilterSpecData->pPHopResvRefreshList->pSentBuffer = NULL;
44670 + pFilterSpecData->pPHopResvRefreshList->SentBufferLen = 0;
44672 + if (NewFilterListNode
44673 + (&pFilterSpecData->pPHopResvRefreshList->pFilterList,
44674 + pFilterSpecData) != E_OK)
44676 + zlog_err ("Cannot create new FILTER LIST node");
44677 + return E_ERR;
44679 + if (pPsb->OutIfIndex == 0)
44681 + if (pPsb->OldPacket.ReceivedRro.rr != NULL)
44683 + AddRro = TRUE;
44686 + else
44688 + if (pFilterSpecData->Rro.rr != NULL)
44690 + AddRro = TRUE;
44693 + if (AddRro)
44695 + if (BuildRRSubObj (pFilterSpecData) != E_OK)
44697 + zlog_err ("an error on BuildRRSubObj %s %d", __FILE__,
44698 + __LINE__);
44702 + return E_OK;
44705 +E_RC
44706 +NewModifiedPath (PSB * pPsb)
44708 + uns8 Shared = 0;
44709 + RSB *pRsb;
44710 + RSB_KEY RsbKey;
44711 + FILTER_LIST *pFilterList, *pFilterListPrev = NULL;
44712 + FILTER_SPEC_DATA *pFilterSpecData;
44714 + memset (&RsbKey, 0, sizeof (RSB_KEY));
44715 + RsbKey.Session = pPsb->PsbKey.Session;
44717 + /* First - get or create RSB */
44718 + if ((pRsb = FindRsb (&RsbKey)) == NULL)
44720 + if ((pRsb = NewRSB (&RsbKey)) == NULL)
44722 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
44723 + return E_ERR;
44725 + pRsb->OldPacket.Session = RsbKey.Session;
44727 + pFilterList = pRsb->OldPacket.pFilterList;
44729 + /* second - get or create filter list node */
44730 + while (pFilterList != NULL)
44732 + if (pFilterList->pFilterSpecData != NULL)
44734 + if ((pFilterList->pFilterSpecData->FilterSpec.IpAddr ==
44735 + pPsb->PsbKey.SenderTemplate.IpAddr)
44736 + && (pFilterList->pFilterSpecData->FilterSpec.LspId ==
44737 + pPsb->PsbKey.SenderTemplate.LspId))
44739 + break;
44742 + else
44744 + zlog_warn
44745 + ("Warning!!! pFilterList->pFilterSpecData is NULL while node is in the list");
44747 + pFilterListPrev = pFilterList;
44748 + pFilterList = pFilterList->next;
44751 + /* create new, if required */
44752 + if (pFilterList == NULL)
44754 + if ((pFilterList =
44755 + (FILTER_LIST *) XMALLOC (MTYPE_RSVP,
44756 + sizeof (FILTER_LIST))) == NULL)
44758 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
44760 + memset (pFilterList, 0, sizeof (FILTER_LIST));
44761 + if ((pFilterList->pFilterSpecData =
44762 + (FILTER_SPEC_DATA *) XMALLOC (MTYPE_RSVP,
44763 + sizeof (FILTER_SPEC_DATA))) == NULL)
44765 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
44766 + XFREE (MTYPE_RSVP, pFilterList);
44767 + return E_ERR;
44769 + memset (pFilterList->pFilterSpecData, 0, sizeof (FILTER_SPEC_DATA));
44770 + pFilterList->pFilterSpecData->FilterSpec.IpAddr =
44771 + pPsb->PsbKey.SenderTemplate.IpAddr;
44772 + pFilterList->pFilterSpecData->FilterSpec.LspId =
44773 + pPsb->PsbKey.SenderTemplate.LspId;
44774 + pFilterList->pFilterSpecData->pPsb = pPsb;
44775 + pFilterList->pFilterSpecData->pPsb->pRsb = pRsb;
44776 + pFilterList->pFilterSpecData->SentLabel.Label =
44777 + pFilterList->pFilterSpecData->pPsb->Label;
44778 + pFilterList->next = pRsb->OldPacket.pFilterList;
44779 + pRsb->OldPacket.pFilterList = pFilterList;
44782 + pFilterSpecData = pFilterList->pFilterSpecData;
44784 + if (LinkFilter2PHopList (pFilterSpecData) != E_OK)
44786 + zlog_err ("An error on LinkFilter2PHopList %s %d", __FILE__, __LINE__);
44787 + return E_ERR;
44790 + if (pPsb->OldPacket.SessionAttributes.CType ==
44791 + SESSION_ATTRIBUTES_RA_CLASS_TYPE)
44793 +#if 0 /* temporary */
44794 + pPsb->OldPacket.SessionAttributes.u.SessAttrRa.Flags |=
44795 + SE_STYLE_DESIRED;
44796 +#endif
44797 + if (pPsb->OldPacket.SessionAttributes.u.SessAttrRa.
44798 + Flags & SE_STYLE_DESIRED)
44800 + Shared = 1;
44801 + pRsb->OldPacket.Style.OptionVector2 = SE_STYLE_BITS;
44803 + else
44805 + pRsb->OldPacket.Style.OptionVector2 = FF_STYLE_BITS;
44808 + else if (pPsb->OldPacket.SessionAttributes.CType ==
44809 + SESSION_ATTRIBUTES_CLASS_TYPE)
44811 +#if 0 /* temporary */
44812 + pPsb->OldPacket.SessionAttributes.u.SessAttr.Flags |= SE_STYLE_DESIRED;
44813 +#endif
44814 + if (pPsb->OldPacket.SessionAttributes.u.SessAttr.
44815 + Flags & SE_STYLE_DESIRED)
44817 + Shared = 1;
44818 + pRsb->OldPacket.Style.OptionVector2 = SE_STYLE_BITS;
44820 + else
44822 + pRsb->OldPacket.Style.OptionVector2 = FF_STYLE_BITS;
44825 + else
44827 + Shared = 1;
44828 + pRsb->OldPacket.Style.OptionVector2 = SE_STYLE_BITS;
44831 + ComposeFlowSpec (pFilterSpecData->pPsb, &pFilterSpecData->FlowSpec);
44833 + return ProcessPHopFilterSpecLists (pRsb, Shared);
44836 +E_RC
44837 +ProcessEffectiveFlows (RSB * pRsb)
44839 + EFFECTIVE_FLOW *pEffectiveFlow = pRsb->pEffectiveFlow;
44840 + uns8 NewFlow;
44841 + zlog_info ("entering ProcessEffectiveFlows");
44842 + zlog_info ("Session.Dest %x .TunnelId %x .ExtTunnelId %x",
44843 + pRsb->RsbKey.Session.Dest,
44844 + pRsb->RsbKey.Session.TunnelId, pRsb->RsbKey.Session.ExtTunelId);
44845 + while (pEffectiveFlow != NULL)
44847 + if ((pEffectiveFlow->MustBeProcessed) &&
44848 + (pEffectiveFlow->TE_InProcess == FALSE))
44850 + FILTER_LIST *pFilterList = pEffectiveFlow->pFilterList;
44851 + FLOW_SPEC_OBJ *pEffectiveFlowSpec;
44852 + memset (&pEffectiveFlow->NewFlowSpec, 0, sizeof (FLOW_SPEC_OBJ));
44853 + NewFlow = FALSE;
44854 + pEffectiveFlowSpec = &pEffectiveFlow->NewFlowSpec;
44855 + while (pFilterList != NULL)
44857 + FLOW_SPEC_OBJ *pFlowSpec;
44858 + if (pFilterList->pFilterSpecData != NULL)
44860 + zlog_info ("processing filter spec %x %x",
44861 + pFilterList->pFilterSpecData->FilterSpec.IpAddr,
44862 + pFilterList->pFilterSpecData->FilterSpec.LspId);
44864 + if (pFilterList->pFilterSpecData->NewFlowSpecValid)
44866 + pFlowSpec = &pFilterList->pFilterSpecData->NewFlowSpec;
44867 + NewFlow = TRUE;
44868 + zlog_info ("New");
44870 + else
44872 + pFlowSpec = &pFilterList->pFilterSpecData->FlowSpec;
44873 + zlog_info ("Not new");
44876 + if (pEffectiveFlowSpec->ServHdr.ServHdr == 0)
44878 + pEffectiveFlowSpec->ServHdr.ServHdr =
44879 + pFlowSpec->ServHdr.ServHdr;
44881 + if (FlowSpec1GreaterThanFlowSpec2
44882 + (pFlowSpec, pEffectiveFlowSpec) == TRUE)
44884 + zlog_info ("Setting Effective flow's BW to %f",
44885 + pFlowSpec->u.CtrlLoad.PeakDataRate);
44886 + *pEffectiveFlowSpec = *pFlowSpec;
44889 + pFilterList = pFilterList->next;
44891 + if ((NewFlow == TRUE) || (memcmp (&pEffectiveFlow->CurrentFlowSpec,
44892 + &pEffectiveFlow->NewFlowSpec,
44893 + sizeof (FLOW_SPEC_OBJ))))
44895 + /* send notification to TE */
44896 + if (FlowSpec1GreaterThanFlowSpec2
44897 + (&pEffectiveFlow->CurrentFlowSpec,
44898 + &pEffectiveFlow->NewFlowSpec) == TRUE)
44900 + pEffectiveFlow->CurrentFlowSpec =
44901 + pEffectiveFlow->NewFlowSpec;
44903 + else
44904 + if (FlowSpec1GreaterThanFlowSpec2
44905 + (&pEffectiveFlow->NewFlowSpec,
44906 + &pEffectiveFlow->CurrentFlowSpec) == TRUE)
44908 + pEffectiveFlow->TE_InProcess = TRUE;
44910 + else if (NewFlow == TRUE)
44912 + pEffectiveFlow->TE_InProcess = TRUE;
44914 + PrepareAndSendMsg2TE4SE (pRsb, pEffectiveFlow);
44916 + else
44918 + zlog_info ("no change...");
44920 + pEffectiveFlow->MustBeProcessed = 0;
44922 + pEffectiveFlow = pEffectiveFlow->next;
44924 + zlog_info ("leaving ProcessEffectiveFlows");
44925 + return E_OK;
44928 +E_RC
44929 +ProcessReceivedFilterSpecs (RSB * pRsb, RSVP_PKT * pRsvpPkt)
44931 + PSB_KEY PsbKey;
44932 + FILTER_LIST *pFilterList, *pFilterListPrev = NULL, *pFilterListNext;
44933 + uns8 ItemExtracted;
44934 + int Shared = 0;
44935 + zlog_info ("entering ProcessReceivedFilterSpecs");
44936 + zlog_info ("Session.Dest %x .TunnelId %x .ExtTunnelId %x",
44937 + pRsb->RsbKey.Session.Dest,
44938 + pRsb->RsbKey.Session.TunnelId, pRsb->RsbKey.Session.ExtTunelId);
44939 + if ((pRsvpPkt->Style.OptionVector2 & 0x001F) == SE_STYLE_BITS)
44941 + Shared = 1;
44943 + else if (!((pRsvpPkt->Style.OptionVector2 & 0x001F) == FF_STYLE_BITS))
44945 + RSVP_PKT RsvpPkt;
44946 + zlog_err ("Unknown style %d", pRsvpPkt->Style.OptionVector2);
44947 + memset (&RsvpPkt, 0, sizeof (RSVP_PKT));
44948 + RsvpPkt.Session = pRsb->RsbKey.Session;
44949 + RsvpPkt.Style = pRsb->OldPacket.Style;
44950 + RsvpPkt.pFilterList = pRsvpPkt->pFilterList;
44951 + RsvpPkt.ErrorSpec.IpAddr = GetRouterId ();
44952 + RsvpPkt.ErrorSpec.ErrCode = UNKNOWN_RESV_STYLE_ERR_CODE;
44953 + RsvpPkt.SentRsvpHop.LIH = pRsvpPkt->SentRsvpHop.LIH;
44954 + if (IpAddrGetByIfIndex
44955 + (RsvpPkt.SentRsvpHop.LIH, &RsvpPkt.SentRsvpHop.PHop) != E_OK)
44957 + zlog_err ("Cannot get IP address by IfIndex");
44958 + return E_ERR;
44960 + if (EncodeAndSendRsvpResvErrMessage
44961 + (&RsvpPkt, pRsvpPkt->ReceivedRsvpHop.PHop, RsvpPkt.SentRsvpHop.LIH,
44962 + 255) != E_OK)
44964 + zlog_err ("An error on encode/send %s %d", __FILE__, __LINE__);
44966 + return E_ERR;
44969 + pFilterList = pRsvpPkt->pFilterList;
44970 + memset (&PsbKey, 0, sizeof (PSB_KEY));
44971 + PsbKey.Session = pRsvpPkt->Session;
44972 + while (pFilterList != NULL)
44974 + FILTER_SPEC_DATA *pFilterSpecData = pFilterList->pFilterSpecData;
44976 + pFilterListNext = pFilterList->next;
44977 + ItemExtracted = FALSE;
44979 + if (pFilterSpecData != NULL)
44981 + FILTER_LIST *pRsbFilterList = pRsb->OldPacket.pFilterList;
44982 + uns8 Found = 0;
44984 + /* First - update the reservations for the existing filters */
44985 + while (pRsbFilterList != NULL)
44987 + if (pRsbFilterList->pFilterSpecData != NULL)
44989 + /* is that the same filter ? */
44990 + if ((pRsbFilterList->pFilterSpecData->FilterSpec.IpAddr ==
44991 + pFilterList->pFilterSpecData->FilterSpec.IpAddr)
44992 + && (pRsbFilterList->pFilterSpecData->FilterSpec.LspId ==
44993 + pFilterList->pFilterSpecData->FilterSpec.LspId))
44995 + zlog_info ("existing filter spec found");
44996 + Found = 1;
44998 + if ((pRsbFilterList->pFilterSpecData->pPsb)
44999 + && (pRsbFilterList->pFilterSpecData->pPsb->
45000 + TE_InProcess == TRUE))
45002 + RSVP_PKT_QUEUE *pQueuedItem;
45003 + RSVP_PKT *pSavedRsvpPkt;
45004 + if (pFilterListPrev == NULL)
45006 + pRsvpPkt->pFilterList = pFilterListNext;
45008 + else
45010 + pFilterListPrev->next = pFilterListNext;
45012 + ItemExtracted = TRUE;
45013 + if ((pSavedRsvpPkt =
45014 + (RSVP_PKT *) XMALLOC (MTYPE_RSVP,
45015 + sizeof (RSVP_PKT))) ==
45016 + NULL)
45018 + zlog_err ("memory allocation failed %s %d",
45019 + __FILE__, __LINE__);
45020 + return E_ERR;
45022 + memcpy (pSavedRsvpPkt, pRsvpPkt, sizeof (RSVP_PKT));
45023 + pSavedRsvpPkt->pFilterList = pFilterList;
45024 + pSavedRsvpPkt->pFilterList->next = NULL;
45025 + pSavedRsvpPkt->pIntegrityObj = NULL; /* temp. */
45026 + pSavedRsvpPkt->pPolicyDataObj = NULL; /* temp. */
45027 + pSavedRsvpPkt->pOpaqueObjList = NULL; /* temp. */
45028 + pSavedRsvpPkt->ReceivedRro.rr = NULL; /* TEMP!!! */
45029 + if ((pQueuedItem =
45030 + (RSVP_PKT_QUEUE *) XMALLOC (MTYPE_RSVP,
45031 + sizeof
45032 + (RSVP_PKT_QUEUE)))
45033 + == NULL)
45035 + zlog_err ("memory allocation failed %s %d",
45036 + __FILE__, __LINE__);
45037 + return E_ERR;
45040 + pQueuedItem->MsgType = RESV_MSG;
45041 + pQueuedItem->pRsvpPkt = pSavedRsvpPkt;
45042 + pQueuedItem->next = NULL;
45043 + if (EnqueueRsvpPacket
45044 + (pQueuedItem,
45045 + &pRsbFilterList->pFilterSpecData->pPsb->
45046 + packet_queue) != E_OK)
45048 + zlog_err ("Cannot enqueue packet %s %d",
45049 + __FILE__, __LINE__);
45050 + return E_ERR;
45052 + break;
45055 + if (StopFilterAgeOutTimer
45056 + (&pRsbFilterList->pFilterSpecData->AgeOutTimer) !=
45057 + E_OK)
45059 + zlog_err ("Cannot stop timer %s %d", __FILE__,
45060 + __LINE__);
45063 + if ((pRsbFilterList->pFilterSpecData->Blocked == TRUE)
45064 + &&
45065 + (FlowSpec1GreaterThanFlowSpec2
45066 + (&pRsbFilterList->pFilterSpecData->
45067 + BlockadeFlowSpec,
45068 + &pFilterSpecData->NewFlowSpec) == FALSE))
45070 + if (StartFilterAgeOutTimer
45071 + (pRsbFilterList->pFilterSpecData->AgeOutValue,
45072 + &pRsbFilterList->pFilterSpecData->AgeOutTimer,
45073 + pRsbFilterList->pFilterSpecData) != E_OK)
45075 + zlog_err ("Cannot add timer %s %d", __FILE__,
45076 + __LINE__);
45078 + break;
45080 + else if (pRsbFilterList->pFilterSpecData->Blocked ==
45081 + TRUE)
45083 + if (StopBlocadeTimer
45084 + (&pRsbFilterList->pFilterSpecData->
45085 + BlocadeTimer) != E_OK)
45087 + zlog_err ("Cannot delete timer %s %d", __FILE__,
45088 + __LINE__);
45090 + pRsbFilterList->pFilterSpecData->Blocked = FALSE;
45092 + if (pRsbFilterList->pFilterSpecData->pPsb->OutIfIndex !=
45093 + pRsvpPkt->ReceivedRsvpHop.LIH)
45095 + zlog_err ("LIH does not match OutIf from PSB");
45096 + break;
45099 + if ((Shared) &&
45100 + ((pFilterSpecData->pEffectiveFlow =
45101 + GetOrCreateEffectiveFlow (pRsb,
45102 + pRsbFilterList->
45103 + pFilterSpecData->pPsb->
45104 + OutIfIndex)) == NULL))
45106 + zlog_err ("Cannot get/create effective flowspec");
45107 + return E_ERR;
45109 + if ((Shared) &&
45110 + (pFilterSpecData->pEffectiveFlow !=
45111 + pRsbFilterList->pFilterSpecData->pEffectiveFlow))
45113 + zlog_info
45114 + ("Deletion of filter_spec from effective_flow list .Src %x .LspId %x",
45115 + pFilterSpecData->FilterSpec.IpAddr,
45116 + pFilterSpecData->FilterSpec.LspId);
45118 + if (DeleteFilterListNode
45119 + (&pRsbFilterList->pFilterSpecData->
45120 + pEffectiveFlow->pFilterList,
45121 + pRsbFilterList->pFilterSpecData) != E_OK)
45123 + zlog_err
45124 + ("Cannot delete filter spec from effective flow list");
45126 + if (pRsbFilterList->pFilterSpecData->
45127 + pEffectiveFlow->pFilterList == NULL)
45129 + if (DeleteEffectiveFlow
45130 + (pRsbFilterList->pFilterSpecData->pPsb->
45131 + pRsb,
45132 + pRsbFilterList->pFilterSpecData->
45133 + pEffectiveFlow) != E_OK)
45135 + zlog_err
45136 + ("Cannot delete effective flow list item");
45139 + else
45141 + pRsbFilterList->pFilterSpecData->
45142 + pEffectiveFlow->MustBeProcessed = 1;
45144 + if (pFilterSpecData->pEffectiveFlow->TE_InProcess ==
45145 + TRUE)
45147 + RSVP_PKT_QUEUE *pQueuedItem;
45148 + RSVP_PKT *pSavedRsvpPkt;
45149 + if (pFilterListPrev == NULL)
45151 + pRsvpPkt->pFilterList = pFilterListNext;
45153 + else
45155 + pFilterListPrev->next = pFilterListNext;
45157 + ItemExtracted = TRUE;
45158 + if ((pSavedRsvpPkt =
45159 + (RSVP_PKT *) XMALLOC (MTYPE_RSVP,
45160 + sizeof (RSVP_PKT)))
45161 + == NULL)
45163 + zlog_err ("memory allocation failed %s %d",
45164 + __FILE__, __LINE__);
45165 + return E_ERR;
45167 + memcpy (pSavedRsvpPkt, pRsvpPkt,
45168 + sizeof (RSVP_PKT));
45169 + pSavedRsvpPkt->pFilterList = pFilterList;
45170 + pSavedRsvpPkt->pFilterList->next = NULL;
45171 + pSavedRsvpPkt->pIntegrityObj = NULL; /* temp. */
45172 + pSavedRsvpPkt->pPolicyDataObj = NULL; /* temp. */
45173 + pSavedRsvpPkt->pOpaqueObjList = NULL; /* temp. */
45174 + pSavedRsvpPkt->ReceivedRro.rr = NULL; /* TEMP!!! */
45175 + if ((pQueuedItem =
45176 + (RSVP_PKT_QUEUE *) XMALLOC (MTYPE_RSVP,
45177 + sizeof
45178 + (RSVP_PKT_QUEUE)))
45179 + == NULL)
45181 + zlog_err ("memory allocation failed %s %d",
45182 + __FILE__, __LINE__);
45183 + return E_ERR;
45186 + pQueuedItem->MsgType = RESV_MSG;
45187 + pQueuedItem->pRsvpPkt = pSavedRsvpPkt;
45188 + pQueuedItem->next = NULL;
45189 + if (EnqueueRsvpPacket
45190 + (pQueuedItem,
45191 + &pRsbFilterList->pFilterSpecData->pPsb->
45192 + packet_queue) != E_OK)
45194 + zlog_err ("Cannot enqueue packet %s %d",
45195 + __FILE__, __LINE__);
45196 + return E_ERR;
45198 + break;
45200 + pRsbFilterList->pFilterSpecData->pEffectiveFlow =
45201 + pFilterSpecData->pEffectiveFlow;
45202 + pRsbFilterList->pFilterSpecData->pEffectiveFlow->
45203 + MustBeProcessed = 1;
45204 + pRsbFilterList->pFilterSpecData->NewFlowSpecValid =
45205 + 1;
45206 + pRsbFilterList->pFilterSpecData->NewFlowSpec =
45207 + pFilterList->pFilterSpecData->NewFlowSpec;
45208 + zlog_info
45209 + ("Adding filter_spec to effective_flow list .Src %x .LspId %x",
45210 + pFilterSpecData->FilterSpec.IpAddr,
45211 + pFilterSpecData->FilterSpec.LspId);
45213 + if (NewFilterListNode
45214 + (&pRsbFilterList->pFilterSpecData->
45215 + pEffectiveFlow->pFilterList,
45216 + pRsbFilterList->pFilterSpecData) != E_OK)
45218 + zlog_err ("Cannot create new FILTER LIST node");
45219 + return E_ERR;
45222 + else if ((Shared)
45223 + && (pFilterSpecData->pEffectiveFlow->
45224 + TE_InProcess == TRUE))
45226 + RSVP_PKT_QUEUE *pQueuedItem;
45227 + RSVP_PKT *pSavedRsvpPkt;
45228 + if (pFilterListPrev == NULL)
45230 + pRsvpPkt->pFilterList = pFilterListNext;
45232 + else
45234 + pFilterListPrev->next = pFilterListNext;
45236 + ItemExtracted = TRUE;
45237 + if ((pSavedRsvpPkt =
45238 + (RSVP_PKT *) XMALLOC (MTYPE_RSVP,
45239 + sizeof (RSVP_PKT))) ==
45240 + NULL)
45242 + zlog_err ("memory allocation failed %s %d",
45243 + __FILE__, __LINE__);
45244 + return E_ERR;
45246 + memcpy (pSavedRsvpPkt, pRsvpPkt, sizeof (RSVP_PKT));
45247 + pSavedRsvpPkt->pFilterList = pFilterList;
45248 + pSavedRsvpPkt->pFilterList->next = NULL;
45249 + pSavedRsvpPkt->pIntegrityObj = NULL; /* temp. */
45250 + pSavedRsvpPkt->pPolicyDataObj = NULL; /* temp. */
45251 + pSavedRsvpPkt->pOpaqueObjList = NULL; /* temp. */
45252 + pSavedRsvpPkt->ReceivedRro.rr = NULL; /* TEMP!!! */
45253 + if ((pQueuedItem =
45254 + (RSVP_PKT_QUEUE *) XMALLOC (MTYPE_RSVP,
45255 + sizeof
45256 + (RSVP_PKT_QUEUE)))
45257 + == NULL)
45259 + zlog_err ("memory allocation failed %s %d",
45260 + __FILE__, __LINE__);
45261 + return E_ERR;
45264 + pQueuedItem->MsgType = RESV_MSG;
45265 + pQueuedItem->pRsvpPkt = pSavedRsvpPkt;
45266 + pQueuedItem->next = NULL;
45267 + if (EnqueueRsvpPacket
45268 + (pQueuedItem,
45269 + &pRsbFilterList->pFilterSpecData->pPsb->
45270 + packet_queue) != E_OK)
45272 + zlog_err ("Cannot enqueue packet %s %d",
45273 + __FILE__, __LINE__);
45274 + return E_ERR;
45276 + break;
45278 + else
45279 + if (memcmp
45280 + (&pRsbFilterList->pFilterSpecData->FlowSpec,
45281 + &pFilterList->pFilterSpecData->NewFlowSpec,
45282 + sizeof (FLOW_SPEC_OBJ)))
45284 + /* if BW should be decreased/increased for the filter */
45285 + pRsbFilterList->pFilterSpecData->NewFlowSpec =
45286 + pFilterList->pFilterSpecData->NewFlowSpec;
45287 + pRsbFilterList->pFilterSpecData->NewFlowSpecValid =
45288 + 1;
45289 + if (Shared)
45291 + pRsbFilterList->pFilterSpecData->
45292 + pEffectiveFlow->MustBeProcessed = 1;
45294 + else
45296 + /* send notification to TE */
45297 + if (FlowSpec1GreaterThanFlowSpec2
45298 + (&pRsbFilterList->pFilterSpecData->
45299 + NewFlowSpec,
45300 + &pFilterList->pFilterSpecData->
45301 + NewFlowSpec) == TRUE)
45303 + zlog_info
45304 + ("Locking Flow %x %x %x %x %x %s %d",
45305 + pRsbFilterList->pFilterSpecData->pPsb->
45306 + pRsb->RsbKey.Session.Dest,
45307 + pRsbFilterList->pFilterSpecData->pPsb->
45308 + pRsb->RsbKey.Session.TunnelId,
45309 + pRsbFilterList->pFilterSpecData->pPsb->
45310 + pRsb->RsbKey.Session.ExtTunelId,
45311 + pRsbFilterList->pFilterSpecData->
45312 + FilterSpec.IpAddr,
45313 + pRsbFilterList->pFilterSpecData->
45314 + FilterSpec.LspId, __FILE__, __LINE__);
45315 + pRsbFilterList->pFilterSpecData->pPsb->
45316 + TE_InProcess = TRUE;
45318 + PrepareAndSendMsg2TE4FF (pRsb,
45319 + pRsbFilterList->
45320 + pFilterSpecData);
45323 + else
45325 + if (StartFilterAgeOutTimer
45326 + (pRsbFilterList->pFilterSpecData->AgeOutValue,
45327 + &pRsbFilterList->pFilterSpecData->AgeOutTimer,
45328 + pRsbFilterList->pFilterSpecData) != E_OK)
45330 + zlog_err ("Cannot add timer %s %d", __FILE__,
45331 + __LINE__);
45334 + Found = 1;
45335 + break;
45338 + pRsbFilterList = pRsbFilterList->next;
45341 + if (Found == 0)
45343 + zlog_info ("the filter spec is new %x %x",
45344 + pFilterSpecData, pFilterSpecData->pPsb);
45345 + PsbKey.SenderTemplate.IpAddr =
45346 + pFilterSpecData->FilterSpec.IpAddr;
45347 + PsbKey.SenderTemplate.LspId = pFilterSpecData->FilterSpec.LspId;
45348 + zlog_info ("%x %x %x %x %x %s %d",
45349 + PsbKey.Session.Dest,
45350 + PsbKey.Session.TunnelId,
45351 + PsbKey.Session.ExtTunelId,
45352 + PsbKey.SenderTemplate.IpAddr,
45353 + PsbKey.SenderTemplate.LspId, __FILE__, __LINE__);
45354 + if ((pFilterSpecData->pPsb = FindPsb (&PsbKey)) == NULL)
45356 + zlog_err ("cannot find PSB %s %d", __FILE__, __LINE__);
45357 + zlog_err ("Generating ResvErr to %x on %x",
45358 + pRsvpPkt->ReceivedRsvpHop.PHop,
45359 + pRsvpPkt->ReceivedRsvpHop.LIH);
45360 + if (GenerateResvErr4SingleFilterSpec
45361 + (pFilterSpecData, pRsb, pRsvpPkt->ReceivedRsvpHop.PHop,
45362 + pRsvpPkt->ReceivedRsvpHop.LIH,
45363 + NO_PATH_INFO_4_RESV_ERR_CODE, 0) != E_OK)
45365 + zlog_err ("Cannot generate/send ResvErr message %s %d",
45366 + __FILE__, __LINE__);
45368 + goto outer_loop_cont;
45371 + if (pFilterSpecData->pPsb->TE_InProcess == TRUE)
45373 + RSVP_PKT_QUEUE *pQueuedItem;
45374 + RSVP_PKT *pSavedRsvpPkt;
45375 + if (pFilterListPrev == NULL)
45377 + pRsvpPkt->pFilterList = pFilterListNext;
45379 + else
45381 + pFilterListPrev->next = pFilterListNext;
45383 + ItemExtracted = TRUE;
45384 + if ((pSavedRsvpPkt =
45385 + (RSVP_PKT *) XMALLOC (MTYPE_RSVP,
45386 + sizeof (RSVP_PKT))) == NULL)
45388 + zlog_err ("memory allocation failed %s %d", __FILE__,
45389 + __LINE__);
45390 + return E_ERR;
45392 + memcpy (pSavedRsvpPkt, pRsvpPkt, sizeof (RSVP_PKT));
45393 + pSavedRsvpPkt->pFilterList = pFilterList;
45394 + pSavedRsvpPkt->pFilterList->next = NULL;
45395 + pSavedRsvpPkt->pIntegrityObj = NULL; /* temp. */
45396 + pSavedRsvpPkt->pPolicyDataObj = NULL; /* temp. */
45397 + pSavedRsvpPkt->pOpaqueObjList = NULL; /* temp. */
45398 + pSavedRsvpPkt->ReceivedRro.rr = NULL; /* TEMP!!! */
45399 + if ((pQueuedItem =
45400 + (RSVP_PKT_QUEUE *) XMALLOC (MTYPE_RSVP,
45401 + sizeof (RSVP_PKT_QUEUE)))
45402 + == NULL)
45404 + zlog_err ("memory allocation failed %s %d", __FILE__,
45405 + __LINE__);
45406 + return E_ERR;
45409 + pQueuedItem->MsgType = RESV_MSG;
45410 + pQueuedItem->pRsvpPkt = pSavedRsvpPkt;
45411 + pQueuedItem->next = NULL;
45412 + if (EnqueueRsvpPacket
45413 + (pQueuedItem,
45414 + &pFilterSpecData->pPsb->packet_queue) != E_OK)
45416 + zlog_err ("Cannot enqueue packet %s %d", __FILE__,
45417 + __LINE__);
45418 + return E_ERR;
45420 + break;
45423 + pFilterSpecData->pPsb->pRsb = pRsb;
45424 + pFilterSpecData->pPsb->pFilterSpecData = pFilterSpecData;
45426 + uns32 val;
45427 + zlog_info ("TimeValue %x", pRsvpPkt->TimeValues.TimeValues);
45428 + val = (uns32) pRsvpPkt->TimeValues.TimeValues / 10000;
45429 + zlog_info ("val %x", val);
45430 + /* 3*R: */
45431 + val *= 3;
45432 + zlog_info ("val %x", val);
45433 + /* (2M+1) * (3*R): */
45434 + val = (2 * ResvRefreshMultiple + 1) * val;
45435 + zlog_info ("val %x", val);
45436 + /* and divide by 4 to get (M + 0.5) * (1.5 * R) */
45437 + pFilterSpecData->AgeOutValue = val >> 2;
45438 + //pFilterSpecData->AgeOutValue = 1;
45439 + zlog_info ("AgeOut value %d", pFilterSpecData->AgeOutValue);
45441 + pFilterSpecData->SentLabel.Label = pFilterSpecData->pPsb->Label;
45443 + if (Shared)
45445 + zlog_info ("and shared...");
45446 + if ((pFilterSpecData->pEffectiveFlow =
45447 + GetOrCreateEffectiveFlow (pRsb,
45448 + pFilterSpecData->pPsb->
45449 + OutIfIndex)) == NULL)
45451 + zlog_err ("Cannot get/create effective flowspec");
45452 + return E_ERR;
45454 + if (pFilterSpecData->pEffectiveFlow->TE_InProcess == TRUE)
45456 + RSVP_PKT_QUEUE *pQueuedItem;
45457 + RSVP_PKT *pSavedRsvpPkt;
45459 + pFilterSpecData->pPsb->pRsb = NULL;
45460 + pFilterSpecData->pPsb->pFilterSpecData = NULL;
45462 + if (pFilterListPrev == NULL)
45464 + pRsvpPkt->pFilterList = pFilterListNext;
45466 + else
45468 + pFilterListPrev->next = pFilterListNext;
45470 + ItemExtracted = TRUE;
45471 + if ((pSavedRsvpPkt =
45472 + (RSVP_PKT *) XMALLOC (MTYPE_RSVP,
45473 + sizeof (RSVP_PKT))) == NULL)
45475 + zlog_err ("memory allocation failed %s %d",
45476 + __FILE__, __LINE__);
45477 + return E_ERR;
45479 + memcpy (pSavedRsvpPkt, pRsvpPkt, sizeof (RSVP_PKT));
45480 + pSavedRsvpPkt->pFilterList = pFilterList;
45481 + pSavedRsvpPkt->pFilterList->next = NULL;
45482 + pSavedRsvpPkt->pIntegrityObj = NULL; /* temp. */
45483 + pSavedRsvpPkt->pPolicyDataObj = NULL; /* temp. */
45484 + pSavedRsvpPkt->pOpaqueObjList = NULL; /* temp. */
45485 + pSavedRsvpPkt->ReceivedRro.rr = NULL; /* TEMP!!! */
45486 + if ((pQueuedItem =
45487 + (RSVP_PKT_QUEUE *) XMALLOC (MTYPE_RSVP,
45488 + sizeof
45489 + (RSVP_PKT_QUEUE))) ==
45490 + NULL)
45492 + zlog_err ("memory allocation failed %s %d",
45493 + __FILE__, __LINE__);
45494 + return E_ERR;
45497 + pQueuedItem->MsgType = RESV_MSG;
45498 + pQueuedItem->pRsvpPkt = pSavedRsvpPkt;
45499 + pQueuedItem->next = NULL;
45500 + if (EnqueueRsvpPacket
45501 + (pQueuedItem,
45502 + &pFilterSpecData->pPsb->packet_queue) != E_OK)
45504 + zlog_err ("Cannot enqueue packet %s %d", __FILE__,
45505 + __LINE__);
45506 + return E_ERR;
45508 + goto outer_loop_cont;
45510 + pFilterSpecData->pEffectiveFlow->MustBeProcessed = 1;
45511 + zlog_info
45512 + ("Adding filter_spec to effective_flow list .Src %x .LspId %x",
45513 + pFilterSpecData->FilterSpec.IpAddr,
45514 + pFilterSpecData->FilterSpec.LspId);
45515 + if (NewFilterListNode
45516 + (&pFilterSpecData->pEffectiveFlow->pFilterList,
45517 + pFilterSpecData) != E_OK)
45519 + zlog_err ("Cannot create new FILTER LIST node");
45520 + goto outer_loop_cont;
45522 + else
45524 + pFilterSpecData->NewFlowSpecValid = 1;
45525 + pFilterSpecData->pEffectiveFlow->MustBeProcessed = 1;
45526 + pFilterList->next = pRsb->OldPacket.pFilterList;
45527 + pRsb->OldPacket.pFilterList = pFilterList;
45530 + else
45532 + pFilterSpecData->NewFlowSpecValid = 1;
45533 + pFilterList->next = pRsb->OldPacket.pFilterList;
45534 + pRsb->OldPacket.pFilterList = pFilterList;
45535 + /* send notification to TE */
45536 + zlog_info ("Locking Flow %x %x %x %x %x %s %d",
45537 + pFilterSpecData->pPsb->pRsb->RsbKey.Session.Dest,
45538 + pFilterSpecData->pPsb->pRsb->RsbKey.Session.
45539 + TunnelId,
45540 + pFilterSpecData->pPsb->pRsb->RsbKey.Session.
45541 + ExtTunelId, pFilterSpecData->FilterSpec.IpAddr,
45542 + pFilterSpecData->FilterSpec.LspId, __FILE__,
45543 + __LINE__);
45544 + pFilterSpecData->pPsb->TE_InProcess = TRUE;
45545 + PrepareAndSendMsg2TE4FF (pRsb,
45546 + pFilterList->pFilterSpecData);
45548 + if (pFilterListPrev == NULL)
45550 + pRsvpPkt->pFilterList = pFilterListNext;
45552 + else
45554 + pFilterListPrev->next = pFilterListNext;
45556 + ItemExtracted = TRUE;
45557 + RsvpStatistics.NewFiltersCount++;
45560 + outer_loop_cont:
45561 + if (ItemExtracted == FALSE)
45563 + pFilterListPrev = pFilterList;
45565 + pFilterList = pFilterListNext;
45567 + if (Shared)
45569 + if (ProcessEffectiveFlows (pRsb) != E_OK)
45571 + zlog_err ("an error on process effective flows");
45572 + return E_ERR;
45575 + zlog_info ("leaving ProcessReceivedFilterSpecs");
45576 + return E_OK;
45579 +static E_RC
45580 +BuildRRSubObj (FILTER_SPEC_DATA * pFilterSpecData)
45582 + PSB *pPsb;
45585 + pPsb = pFilterSpecData->pPsb;
45586 + if ((pFilterSpecData->pPHopResvRefreshList->pAddedRro =
45587 + (RR_SUBOBJ *) XMALLOC (MTYPE_RSVP, sizeof (RR_SUBOBJ))) == NULL)
45589 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
45590 + return E_ERR;
45592 + else
45594 + IPV4_ADDR IpAddr;
45595 + uns8 LabelRecordingDesired = 0;
45596 + memset (pFilterSpecData->pPHopResvRefreshList->pAddedRro, 0,
45597 + sizeof (RR_SUBOBJ));
45598 + pFilterSpecData->pPHopResvRefreshList->pAddedRro->SubObjHdr.Type =
45599 + RRO_SUBTYPE_IPV4;
45600 + pFilterSpecData->pPHopResvRefreshList->pAddedRro->SubObjHdr.Length = 8;
45601 + pFilterSpecData->pPHopResvRefreshList->pAddedRro->u.Ipv4.PrefixLen = 32;
45602 + zlog_info ("inside of BuildRRSubObj %s %d...", __FILE__, __LINE__);
45603 + if (IpAddrGetByIfIndex (pPsb->InIfIndex, &IpAddr) != E_OK)
45605 + zlog_err ("Cannot set RSVP HOP %s %d", __FILE__, __LINE__);
45606 + return E_ERR;
45608 + pFilterSpecData->pPHopResvRefreshList->pAddedRro->u.Ipv4.IpAddr =
45609 + IpAddr;
45610 + if (pPsb->OldPacket.SessionAttributes.CType ==
45611 + SESSION_ATTRIBUTES_RA_IPV4_CTYPE)
45613 + if (pPsb->OldPacket.SessionAttributes.u.SessAttrRa.
45614 + Flags & LABEL_RECORDING_DESIRED)
45616 + LabelRecordingDesired = 1;
45619 + else if (pPsb->OldPacket.SessionAttributes.CType ==
45620 + SESSION_ATTRIBUTES_IPV4_CTYPE)
45622 + if (pPsb->OldPacket.SessionAttributes.u.SessAttr.
45623 + Flags & LABEL_RECORDING_DESIRED)
45625 + LabelRecordingDesired = 1;
45628 + if (LabelRecordingDesired == 1)
45630 + zlog_info ("inside of BuildRRSubObj %s %d...", __FILE__, __LINE__);
45631 + if ((pFilterSpecData->pPHopResvRefreshList->pAddedRro->next =
45632 + (RR_SUBOBJ *) XMALLOC (MTYPE_RSVP,
45633 + sizeof (RR_SUBOBJ))) == NULL)
45635 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
45636 + return E_ERR;
45638 + else
45640 + memset (pFilterSpecData->pPHopResvRefreshList->pAddedRro->next,
45641 + 0, sizeof (RR_SUBOBJ));
45642 + pFilterSpecData->pPHopResvRefreshList->pAddedRro->next->
45643 + SubObjHdr.Type = RRO_SUBTYPE_LABEL;
45644 + pFilterSpecData->pPHopResvRefreshList->pAddedRro->next->
45645 + SubObjHdr.Length = 8;
45646 + pFilterSpecData->pPHopResvRefreshList->pAddedRro->next->u.Label.
45647 + CType = COMMON_CTYPE;
45648 + pFilterSpecData->pPHopResvRefreshList->pAddedRro->next->u.Label.
45649 + Flags = 0x01;
45650 + pFilterSpecData->pPHopResvRefreshList->pAddedRro->next->u.Label.
45651 + Label = pFilterSpecData->SentLabel.Label;
45655 + return E_OK;
45658 +E_RC
45659 +ProcessPHopFilterSpecLists (RSB * pRsb, uns8 Shared)
45661 + PHOP_RESV_REFRESH_LIST *pPHopResvRefreshList;
45662 + FILTER_LIST *pFilterList;
45663 + int FlowCount = 0;
45664 + zlog_info ("entering ProcessPHopFilterSpecLists");
45665 + pPHopResvRefreshList = pRsb->pPHopResvRefreshList;
45666 + while (pPHopResvRefreshList != NULL)
45668 + if (pPHopResvRefreshList->MustBeProcessed)
45670 + if (Shared)
45672 + memset (&pPHopResvRefreshList->FwdFlowSpec, 0,
45673 + sizeof (FLOW_SPEC_OBJ));
45676 + pFilterList = pPHopResvRefreshList->pFilterList;
45678 + while (pFilterList != NULL)
45680 + if ((pFilterList->pFilterSpecData->Blocked == TRUE) &&
45681 + (FlowSpec1GreaterThanFlowSpec2
45682 + (&pFilterList->pFilterSpecData->BlockadeFlowSpec,
45683 + &pFilterList->pFilterSpecData->FlowSpec) == FALSE))
45685 + pFilterList = pFilterList->next;
45686 + continue;
45688 + else if (pFilterList->pFilterSpecData->Blocked == TRUE)
45690 + if (StopBlocadeTimer
45691 + (&pFilterList->pFilterSpecData->BlocadeTimer) != E_OK)
45693 + zlog_err ("Cannot delete timer %s %d", __FILE__,
45694 + __LINE__);
45696 + pFilterList->pFilterSpecData->Blocked = FALSE;
45698 + if (Shared)
45700 + if (pPHopResvRefreshList->FwdFlowSpec.ServHdr.ServHdr == 0)
45702 + pPHopResvRefreshList->FwdFlowSpec.ServHdr.ServHdr =
45703 + pFilterList->pFilterSpecData->NewFlowSpec.ServHdr.
45704 + ServHdr;
45707 + CheckAndSetFlowSpecObj (pFilterList->pFilterSpecData->pPsb,
45708 + &pFilterList->pFilterSpecData->
45709 + FlowSpec,
45710 + &pPHopResvRefreshList->FwdFlowSpec);
45712 + FlowCount++;
45713 + pFilterList = pFilterList->next;
45715 + if (FlowCount)
45717 + if (ResvRefreshProc (pRsb, pPHopResvRefreshList) != E_OK)
45719 + zlog_err ("an error on resv refresh proc");
45722 + pPHopResvRefreshList->MustBeProcessed = 0;
45724 + pPHopResvRefreshList = pPHopResvRefreshList->next;
45727 + zlog_info ("leaving ProcessPHopFilterSpecLists");
45728 + return E_OK;
45731 +E_RC
45732 +ProcessForwardedSEFilterSpecsByIfIndex (RSB * pRsb, uns32 IfIndex)
45734 + FILTER_LIST *pFilterList;
45735 + PSB *pPsb;
45736 + uns8 Ingress = FALSE;
45737 + EFFECTIVE_FLOW *pEffectiveFlow = pRsb->pEffectiveFlow;
45738 + zlog_info ("entering ProcessForwardedSEFilterSpecsByIfIndex");
45739 + while (pEffectiveFlow != NULL)
45741 + if (pEffectiveFlow->IfIndex == IfIndex)
45743 + break;
45745 + pEffectiveFlow = pEffectiveFlow->next;
45747 + if (pEffectiveFlow == NULL)
45749 + zlog_err ("Cannot find effective flow");
45750 + return E_ERR;
45752 + pEffectiveFlow->CurrentFlowSpec = pEffectiveFlow->NewFlowSpec;
45753 + pFilterList = pEffectiveFlow->pFilterList;
45754 + pEffectiveFlow->TE_InProcess = FALSE;
45755 + while (pFilterList != NULL)
45757 + FILTER_SPEC_DATA *pFilterSpecData = pFilterList->pFilterSpecData;
45759 + if (pFilterSpecData != NULL)
45761 + if ((pFilterSpecData->Blocked == TRUE) &&
45762 + (FlowSpec1GreaterThanFlowSpec2
45763 + (&pFilterSpecData->BlockadeFlowSpec,
45764 + &pFilterSpecData->FlowSpec) == FALSE))
45766 + pFilterList = pFilterList->next;
45767 + continue;
45769 + else if (pFilterSpecData->Blocked == TRUE)
45771 + if (StopBlocadeTimer (&pFilterSpecData->BlocadeTimer) != E_OK)
45773 + zlog_err ("Cannot delete timer %s %d", __FILE__, __LINE__);
45775 + pFilterSpecData->Blocked = FALSE;
45777 + pPsb = pFilterSpecData->pPsb;
45778 + if (pFilterSpecData->NewFlowSpecValid)
45780 + pFilterSpecData->FlowSpec = pFilterSpecData->NewFlowSpec;
45781 + pFilterSpecData->NewFlowSpecValid = 0;
45782 + if (StartFilterAgeOutTimer (pFilterSpecData->AgeOutValue,
45783 + &pFilterSpecData->AgeOutTimer,
45784 + pFilterSpecData) != E_OK)
45786 + zlog_err ("Cannot start timer %s %d", __FILE__, __LINE__);
45789 + if (pFilterSpecData->pPsb->InIfIndex == 0)
45791 + zlog_info ("Congratulations: RESV has reached Ingress!!");
45792 + Ingress = TRUE;
45796 + if (pFilterSpecData->pPsb->InIfIndex == 0)
45798 + pFilterList = pFilterList->next;
45799 + continue;
45801 + if (LinkFilter2PHopList (pFilterSpecData) != E_OK)
45803 + zlog_err ("An error on LinkFilter2PHopList %s %d", __FILE__,
45804 + __LINE__);
45805 + goto outer_loop_cont;
45808 + outer_loop_cont:
45809 + pFilterList = pFilterList->next;
45811 + if (Ingress == FALSE)
45813 + return ProcessPHopFilterSpecLists (pRsb, 1);
45815 + return E_OK;
45818 +E_RC
45819 +ProcessFailedSEFilterSpecsByIfIndex (RSB * pRsb, uns32 IfIndex)
45821 + FILTER_LIST *pFilterList;
45822 + uns8 Ingress = FALSE;
45823 + EFFECTIVE_FLOW *pEffectiveFlow = pRsb->pEffectiveFlow;
45824 + RSVP_PKT RsvpPkt;
45825 + IPV4_ADDR NHop = 0;
45826 + zlog_info ("entering ProcessFailedSEFilterSpecsByIfIndex");
45827 + memset (&RsvpPkt, 0, sizeof (RSVP_PKT));
45828 + RsvpPkt.Session = pRsb->RsbKey.Session;
45829 + RsvpPkt.Style = pRsb->OldPacket.Style;
45830 + RsvpPkt.ErrorSpec.IpAddr = GetRouterId ();
45831 + RsvpPkt.ErrorSpec.ErrCode = ADMISSION_CTRL_FAILURE_ERR_CODE;
45832 + RsvpPkt.ErrorSpec.ErrVal = BW_UNAVAILABLE;
45833 + RsvpPkt.SentRsvpHop.LIH = IfIndex;
45834 + RsvpPkt.SentRsvpHop.PHop = GetRouterId ();
45835 + while (pEffectiveFlow != NULL)
45837 + if (pEffectiveFlow->IfIndex == IfIndex)
45839 + break;
45841 + pEffectiveFlow = pEffectiveFlow->next;
45843 + if (pEffectiveFlow == NULL)
45845 + zlog_err ("Cannot find effective flow");
45846 + return E_ERR;
45848 + pEffectiveFlow->CurrentFlowSpec = pEffectiveFlow->NewFlowSpec;
45849 + pFilterList = pEffectiveFlow->pFilterList;
45850 + pEffectiveFlow->TE_InProcess = FALSE;
45851 + while (pFilterList != NULL)
45853 + FILTER_SPEC_DATA *pFilterSpecData = pFilterList->pFilterSpecData;
45855 + if (pFilterSpecData != NULL)
45857 + if (pFilterSpecData->NewFlowSpecValid)
45859 + if (StartBlocadeTimer (pFilterSpecData->BlocadeValue,
45860 + &pFilterSpecData->BlocadeTimer,
45861 + pFilterSpecData) != E_OK)
45863 + zlog_err ("Cannot start blocade timer %s %d", __FILE__,
45864 + __LINE__);
45866 + else
45868 + pFilterSpecData->Blocked = TRUE;
45870 + memset (&pFilterSpecData->NewFlowSpec, 0,
45871 + sizeof (FLOW_SPEC_OBJ));
45872 + pFilterSpecData->NewFlowSpecValid = 0;
45873 + if (StartFilterAgeOutTimer (pFilterSpecData->AgeOutValue,
45874 + &pFilterSpecData->AgeOutTimer,
45875 + pFilterSpecData) != E_OK)
45877 + zlog_err ("Cannot start timer %s %d", __FILE__, __LINE__);
45880 + if (pFilterSpecData->pPsb->InIfIndex == 0)
45882 + Ingress = TRUE;
45884 + NHop = pFilterSpecData->pPsb->NextHop;
45885 + if (NewFilterListNode (&RsvpPkt.pFilterList, pFilterSpecData) !=
45886 + E_OK)
45888 + zlog_err ("Cannot add filter to filter list %s %d",
45889 + __FILE__, __LINE__);
45892 + if (pFilterSpecData->pPsb->InIfIndex == 0)
45894 + pFilterList = pFilterList->next;
45895 + continue;
45898 + if (LinkFilter2PHopList (pFilterSpecData) != E_OK)
45900 + zlog_err ("An error on LinkFilter2PHopList %s %d", __FILE__,
45901 + __LINE__);
45902 + goto outer_loop_cont;
45906 + outer_loop_cont:
45907 + pFilterList = pFilterList->next;
45909 + if (EncodeAndSendRsvpResvErrMessage (&RsvpPkt, NHop, IfIndex, 255) != E_OK)
45911 + zlog_err ("Cannot encode/send ResvErr message %s %d", __FILE__,
45912 + __LINE__);
45914 + pFilterList = RsvpPkt.pFilterList;
45915 + while (pFilterList != NULL)
45917 + FILTER_LIST *pNext = pFilterList->next;
45918 + XFREE (MTYPE_RSVP, pFilterList);
45919 + pFilterList = pNext;
45921 + if (Ingress == FALSE)
45923 + return ProcessPHopFilterSpecLists (pRsb, 1);
45925 + return E_OK;
45928 +E_RC
45929 +ProcessForwardedFFFilterSpec (RSB * pRsb, FILTER_SPEC_OBJ * pFilterSpecObj)
45931 + PSB *pPsb;
45932 + FILTER_SPEC_DATA *pFilterSpecData = NULL;
45933 + FILTER_LIST *pFilterList = pRsb->OldPacket.pFilterList;
45934 + zlog_info ("entering ProcessForwardedFFFilterSpec");
45935 + while (pFilterList != NULL)
45937 + if ((pFilterSpecData = pFilterList->pFilterSpecData) != NULL)
45939 + if (memcmp (&pFilterSpecData->FilterSpec,
45940 + pFilterSpecObj, sizeof (FILTER_SPEC_OBJ)) == 0)
45942 + break;
45945 + pFilterSpecData = NULL;
45946 + pFilterList = pFilterList->next;
45948 + if (pFilterSpecData != NULL)
45950 + pFilterSpecData->pPsb->TE_InProcess = FALSE;
45952 + if ((pFilterSpecData->Blocked == TRUE) &&
45953 + (FlowSpec1GreaterThanFlowSpec2 (&pFilterSpecData->BlockadeFlowSpec,
45954 + &pFilterSpecData->FlowSpec) ==
45955 + FALSE))
45957 + return E_OK;
45959 + else if (pFilterSpecData->Blocked == TRUE)
45961 + if (StopBlocadeTimer (&pFilterSpecData->BlocadeTimer) != E_OK)
45963 + zlog_err ("Cannot delete timer %s %d", __FILE__, __LINE__);
45965 + pFilterSpecData->Blocked = FALSE;
45967 + pPsb = pFilterSpecData->pPsb;
45968 + if (pFilterSpecData->NewFlowSpecValid)
45970 + pFilterSpecData->FlowSpec = pFilterSpecData->NewFlowSpec;
45971 + pFilterSpecData->NewFlowSpecValid = 0;
45972 + if (StartFilterAgeOutTimer (pFilterSpecData->AgeOutValue,
45973 + &pFilterSpecData->AgeOutTimer,
45974 + pFilterSpecData) != E_OK)
45976 + zlog_err ("Cannot start timer %s %d", __FILE__, __LINE__);
45979 + if (pFilterSpecData->pPsb->InIfIndex == 0)
45981 + return E_OK;
45983 + if (LinkFilter2PHopList (pFilterSpecData) != E_OK)
45985 + zlog_err ("An error on LinkFilter2PHopList %s %d", __FILE__,
45986 + __LINE__);
45988 + return ProcessPHopFilterSpecLists (pRsb, 0);
45990 + zlog_info ("leaving ProcessForwardedFFFilterSpec");
45991 + return E_ERR;
45994 +E_RC
45995 +ProcessFailedFFFilterSpec (RSB * pRsb, FILTER_SPEC_OBJ * pFilterSpecObj)
45997 + FILTER_SPEC_DATA *pFilterSpecData = NULL;
45998 + FILTER_LIST *pFilterList = pRsb->OldPacket.pFilterList;
45999 + zlog_info ("entering ProcessFailedFFFilterSpec");
46000 + while (pFilterList != NULL)
46002 + if ((pFilterSpecData = pFilterList->pFilterSpecData) != NULL)
46004 + if (memcmp (&pFilterSpecData->FilterSpec,
46005 + pFilterSpecObj, sizeof (FILTER_SPEC_OBJ)) == 0)
46007 + break;
46010 + pFilterSpecData = NULL;
46011 + pFilterList = pFilterList->next;
46013 + if (pFilterSpecData != NULL)
46015 + pFilterSpecData->pPsb->TE_InProcess = FALSE;
46016 + if (StartBlocadeTimer (pFilterSpecData->BlocadeValue,
46017 + &pFilterSpecData->BlocadeTimer,
46018 + pFilterSpecData) != E_OK)
46020 + zlog_err ("Cannot start blocade timer %s %d", __FILE__, __LINE__);
46022 + else
46024 + pFilterSpecData->Blocked = TRUE;
46027 + if (pFilterSpecData->NewFlowSpecValid)
46029 + memset (&pFilterSpecData->NewFlowSpec, 0, sizeof (FLOW_SPEC_OBJ));
46030 + pFilterSpecData->NewFlowSpecValid = 0;
46031 + if (StartFilterAgeOutTimer (pFilterSpecData->AgeOutValue,
46032 + &pFilterSpecData->AgeOutTimer,
46033 + pFilterSpecData) != E_OK)
46035 + zlog_err ("Cannot start timer %s %d", __FILE__, __LINE__);
46038 + if (GenerateResvErr4SingleFilterSpec (pFilterSpecData,
46039 + pRsb,
46040 + pFilterSpecData->pPsb->NextHop,
46041 + pFilterSpecData->pPsb->OutIfIndex,
46042 + ADMISSION_CTRL_FAILURE_ERR_CODE,
46043 + BW_UNAVAILABLE) != E_OK)
46045 + zlog_err ("Cannot generate ResvErr message %s %d", __FILE__,
46046 + __LINE__);
46048 + if (pFilterSpecData->pPsb->InIfIndex == 0)
46050 + return E_OK;
46052 + if (LinkFilter2PHopList (pFilterSpecData) != E_OK)
46054 + zlog_err ("An error on LinkFilter2PHopList %s %d", __FILE__,
46055 + __LINE__);
46057 + return ProcessPHopFilterSpecLists (pRsb, 0);
46059 + zlog_info ("leaving ProcessFailedFFFilterSpec");
46060 + return E_ERR;
46063 +E_RC
46064 +ProcessRsvpResvMessage (RSVP_PKT * pRsvpPkt)
46066 + RSB *pRsb;
46067 + RSB_KEY RsbKey;
46068 + zlog_info ("entering ProcessRsvpResvMessage");
46069 + RsvpStatistics.ResvMsgCount++;
46070 + memset (&RsbKey, 0, sizeof (RSB_KEY));
46071 + RsbKey.Session = pRsvpPkt->Session;
46073 + zlog_info ("Session.Dest %x .TunnelId %x .ExtTunnelId %x",
46074 + RsbKey.Session.Dest,
46075 + RsbKey.Session.TunnelId, RsbKey.Session.ExtTunelId);
46077 + if ((pRsb = FindRsb (&RsbKey)) == NULL)
46079 + if ((pRsb = NewRSB (&RsbKey)) == NULL)
46081 + return E_ERR;
46083 + pRsb->OldPacket.Session = pRsvpPkt->Session;
46084 + pRsb->OldPacket.Style = pRsvpPkt->Style;
46086 + else
46088 + if (memcmp (&pRsb->OldPacket.Style,
46089 + &pRsvpPkt->Style, sizeof (STYLE_OBJ)))
46091 + RSVP_PKT RsvpPkt;
46092 + zlog_err ("Style object differs");
46094 + memset (&RsvpPkt, 0, sizeof (RSVP_PKT));
46095 + RsvpPkt.Session = pRsb->RsbKey.Session;
46096 + RsvpPkt.Style = pRsb->OldPacket.Style;
46097 + RsvpPkt.pFilterList = pRsvpPkt->pFilterList;
46098 + RsvpPkt.ErrorSpec.IpAddr = GetRouterId ();
46099 + RsvpPkt.ErrorSpec.ErrCode = CONFLICTING_RESV_STYLES_ERR_CODE;
46100 + RsvpPkt.SentRsvpHop.LIH = pRsvpPkt->SentRsvpHop.LIH;
46101 + if (IpAddrGetByIfIndex
46102 + (RsvpPkt.SentRsvpHop.LIH, &RsvpPkt.SentRsvpHop.PHop) != E_OK)
46104 + zlog_err ("Cannot get IP address by IfIndex");
46105 + return E_ERR;
46107 + if (EncodeAndSendRsvpResvErrMessage
46108 + (&RsvpPkt, pRsvpPkt->ReceivedRsvpHop.PHop,
46109 + RsvpPkt.SentRsvpHop.LIH, 255) != E_OK)
46111 + zlog_err ("An error on encode/send %s %d", __FILE__, __LINE__);
46113 + return E_ERR;
46116 + pRsb->OldPacket.ReceivedRsvpHop = pRsvpPkt->ReceivedRsvpHop;
46117 + pRsb->OldPacket.pIntegrityObj = pRsvpPkt->pIntegrityObj;
46118 + pRsvpPkt->pIntegrityObj = NULL;
46119 + pRsb->OldPacket.pPolicyDataObj = pRsvpPkt->pPolicyDataObj;
46120 + pRsvpPkt->pPolicyDataObj = NULL;
46121 + pRsb->OldPacket.pOpaqueObjList = pRsvpPkt->pOpaqueObjList;
46122 + pRsvpPkt->pOpaqueObjList = NULL;
46123 + pRsb->OldPacket.ResvConf = pRsvpPkt->ResvConf;
46124 + pRsb->OldPacket.TimeValues = pRsvpPkt->TimeValues;
46126 + if (ProcessReceivedFilterSpecs (pRsb, pRsvpPkt) != E_OK)
46128 + zlog_err ("An error on ProceessReceivedFilterSpecs");
46129 + return E_ERR;
46131 + if (pRsb->OldPacket.pFilterList == NULL)
46133 + FreeRSB (pRsb);
46134 + pRsb = NULL;
46136 + FreeRsvpPkt (pRsvpPkt);
46137 + zlog_info ("leaving ProcessRsvpResvMessage");
46138 + return E_OK;
46141 +static void
46142 +PrepareAndSendMsg2TE4SE (RSB * pRsb, EFFECTIVE_FLOW * pEffectiveFlow)
46144 + TE_API_MSG msg;
46145 + FILTER_LIST *pFilterList;
46146 + int i;
46147 + FILTER_LIST *pFilterListHead = pEffectiveFlow->pFilterList;
46149 + memset (&msg, 0, sizeof (msg));
46150 + msg.NotificationType = RESV_MSG_NOTIFICATION;
46151 + msg.u.ResvNotification.RsbKey = pRsb->RsbKey;
46152 + msg.u.ResvNotification.SharedExplicit = 1;
46153 + msg.u.ResvNotification.u.FilterDataSE.IfIndex = pEffectiveFlow->IfIndex;
46154 + msg.u.ResvNotification.PleaseReply = pEffectiveFlow->TE_InProcess;
46156 + if (pFilterListHead != NULL)
46158 + if (pFilterListHead->pFilterSpecData != NULL)
46160 + msg.u.ResvNotification.Ingress =
46161 + (pFilterListHead->pFilterSpecData->pPsb->InIfIndex == 0);
46163 + if (pFilterListHead->pFilterSpecData->pPsb->OldPacket.
46164 + SessionAttributes.CType == SESSION_ATTRIBUTES_RA_IPV4_CTYPE)
46166 + msg.u.ResvNotification.u.FilterDataSE.HoldPrio
46168 + pFilterListHead->pFilterSpecData->pPsb->OldPacket.
46169 + SessionAttributes.u.SessAttrRa.HoldPrio;
46170 + msg.u.ResvNotification.u.FilterDataSE.SetupPrio =
46171 + pFilterListHead->pFilterSpecData->pPsb->OldPacket.
46172 + SessionAttributes.u.SessAttrRa.SetPrio;
46174 + else if (pFilterListHead->pFilterSpecData->pPsb->OldPacket.
46175 + SessionAttributes.CType == SESSION_ATTRIBUTES_IPV4_CTYPE)
46177 + msg.u.ResvNotification.u.FilterDataSE.HoldPrio
46179 + pFilterListHead->pFilterSpecData->pPsb->OldPacket.
46180 + SessionAttributes.u.SessAttr.HoldPrio;
46181 + msg.u.ResvNotification.u.FilterDataSE.SetupPrio =
46182 + pFilterListHead->pFilterSpecData->pPsb->OldPacket.
46183 + SessionAttributes.u.SessAttr.SetPrio;
46185 + else
46187 + msg.u.ResvNotification.u.FilterDataSE.HoldPrio =
46188 + msg.u.ResvNotification.u.FilterDataSE.SetupPrio = 4;
46192 + if (pEffectiveFlow->NewFlowSpec.ServHdr.ServHdr ==
46193 + FLOW_SPEC_CTRL_LOAD_SERV_NUMBER)
46195 + msg.u.ResvNotification.u.FilterDataSE.BW =
46196 + pEffectiveFlow->NewFlowSpec.u.CtrlLoad.PeakDataRate;
46198 + else if (pEffectiveFlow->NewFlowSpec.ServHdr.ServHdr ==
46199 + FLOW_SPEC_GUAR_SERV_NUMBER)
46201 + msg.u.ResvNotification.u.FilterDataSE.BW =
46202 + pEffectiveFlow->NewFlowSpec.u.Guar.CtrlLoad.PeakDataRate;
46204 + for (i = 0, pFilterList = pFilterListHead; pFilterList != NULL;
46205 + pFilterList = pFilterList->next)
46207 + FILTER_SPEC_DATA *pFilterSpecData = pFilterList->pFilterSpecData;
46208 + if (pFilterSpecData != NULL)
46210 + if ((pFilterSpecData->NewFlowSpecValid) &&
46211 + (pFilterSpecData->pPsb->TE_InProcess == FALSE))
46213 + msg.u.ResvNotification.u.FilterDataSE.FilterDataArraySE[i].
46214 + FilterSpec = pFilterSpecData->FilterSpec;
46216 + msg.u.ResvNotification.u.FilterDataSE.FilterDataArraySE[i].
46217 + ReceivedLabel = pFilterSpecData->ReceivedLabel.Label;
46218 + msg.u.ResvNotification.u.FilterDataSE.FilterDataArraySE[i].
46219 + AllocatedLabel = pFilterSpecData->pPsb->Label;
46220 + i++;
46221 + zlog_info ("Locking Flow %x %x %x %x %x %s %d",
46222 + pFilterSpecData->pPsb->pRsb->RsbKey.Session.Dest,
46223 + pFilterSpecData->pPsb->pRsb->RsbKey.Session.TunnelId,
46224 + pFilterSpecData->pPsb->pRsb->RsbKey.Session.
46225 + ExtTunelId, pFilterSpecData->FilterSpec.IpAddr,
46226 + pFilterSpecData->FilterSpec.LspId, __FILE__,
46227 + __LINE__);
46228 + pFilterSpecData->pPsb->TE_InProcess = TRUE;
46232 + msg.u.ResvNotification.u.FilterDataSE.FilterSpecNumber = i;
46233 + zlog_info ("sending message to TE upon RESV");
46234 + rsvp_send_msg (&msg, sizeof (msg));
46237 +static void
46238 +PrepareAndSendMsg2TE4FF (RSB * pRsb, FILTER_SPEC_DATA * pFilterSpecData)
46240 + TE_API_MSG msg;
46241 + FLOW_SPEC_OBJ *pFlowSpecObj;
46242 + memset (&msg, 0, sizeof (msg));
46243 + msg.NotificationType = RESV_MSG_NOTIFICATION;
46244 + msg.u.ResvNotification.RsbKey = pRsb->RsbKey;
46245 + msg.u.ResvNotification.SharedExplicit = 0;
46246 + msg.u.ResvNotification.u.FilterDataFF.IfIndex =
46247 + pFilterSpecData->pPsb->OutIfIndex;
46248 + msg.u.ResvNotification.PleaseReply = pFilterSpecData->pPsb->TE_InProcess;
46249 + if (pFilterSpecData == NULL)
46251 + zlog_err ("pFilterSpecData == NULL %s %d", __FILE__, __LINE__);
46252 + return;
46254 + msg.u.ResvNotification.Ingress = (pFilterSpecData->pPsb->InIfIndex == 0);
46255 + pFlowSpecObj =
46256 + (pFilterSpecData->NewFlowSpecValid) ? &pFilterSpecData->
46257 + NewFlowSpec : &pFilterSpecData->FlowSpec;
46258 + msg.u.ResvNotification.u.FilterDataFF.FilterSpec =
46259 + pFilterSpecData->FilterSpec;
46260 + if (pFilterSpecData->NewFlowSpec.ServHdr.ServHdr ==
46261 + FLOW_SPEC_CTRL_LOAD_SERV_NUMBER)
46263 + msg.u.ResvNotification.u.FilterDataFF.BW =
46264 + pFlowSpecObj->u.CtrlLoad.PeakDataRate;
46266 + else if (pFilterSpecData->NewFlowSpec.ServHdr.ServHdr ==
46267 + FLOW_SPEC_GUAR_SERV_NUMBER)
46269 + msg.u.ResvNotification.u.FilterDataFF.BW =
46270 + pFlowSpecObj->u.Guar.CtrlLoad.PeakDataRate;
46272 + msg.u.ResvNotification.u.FilterDataFF.ReceivedLabel =
46273 + pFilterSpecData->ReceivedLabel.Label;
46274 + if (pFilterSpecData->pPsb->OldPacket.SessionAttributes.CType ==
46275 + SESSION_ATTRIBUTES_RA_IPV4_CTYPE)
46277 + msg.u.ResvNotification.u.FilterDataFF.HoldPrio
46279 + pFilterSpecData->pPsb->OldPacket.SessionAttributes.u.SessAttrRa.
46280 + HoldPrio;
46281 + msg.u.ResvNotification.u.FilterDataFF.SetupPrio =
46282 + pFilterSpecData->pPsb->OldPacket.SessionAttributes.u.SessAttrRa.
46283 + SetPrio;
46285 + else if (pFilterSpecData->pPsb->OldPacket.SessionAttributes.CType ==
46286 + SESSION_ATTRIBUTES_IPV4_CTYPE)
46288 + msg.u.ResvNotification.u.FilterDataFF.HoldPrio
46290 + pFilterSpecData->pPsb->OldPacket.SessionAttributes.u.SessAttr.
46291 + HoldPrio;
46292 + msg.u.ResvNotification.u.FilterDataFF.SetupPrio =
46293 + pFilterSpecData->pPsb->OldPacket.SessionAttributes.u.SessAttr.SetPrio;
46295 + zlog_info ("sending message to TE upon RESV FF");
46296 + rsvp_send_msg (&msg, sizeof (msg));
46299 +void
46300 +RsbDequeueAndInvokeMessages (RSB * pRsb)
46302 + FILTER_LIST *pFilterList;
46303 + RSVP_PKT_QUEUE *pQueuedItem;
46304 + if (!pRsb)
46305 + return;
46306 + pFilterList = pRsb->OldPacket.pFilterList;
46307 + while (pFilterList != NULL)
46309 + while ((pFilterList->pFilterSpecData->pPsb->TE_InProcess == FALSE) &&
46310 + (((pFilterList->pFilterSpecData->pEffectiveFlow != NULL)
46311 + && (pFilterList->pFilterSpecData->pEffectiveFlow->
46312 + TE_InProcess == FALSE))
46313 + || (pFilterList->pFilterSpecData->pEffectiveFlow == NULL))
46314 + &&
46315 + ((pQueuedItem =
46316 + DequeueRsvpPacket (&pFilterList->pFilterSpecData->pPsb->
46317 + packet_queue)) != NULL))
46319 + RSVP_PKT *pRsvpPkt;
46320 + uns8 MsgType;
46321 + uns32 InIfIndex = pQueuedItem->InIfIndex;
46322 + IPV4_ADDR SourceIp = pQueuedItem->SourceIp;
46323 + uns8 ttl = pQueuedItem->ttl;
46324 + pRsvpPkt = pQueuedItem->pRsvpPkt;
46325 + MsgType = pQueuedItem->MsgType;
46326 + XFREE (MTYPE_RSVP, pQueuedItem);
46327 + if (MsgType == PATH_MSG)
46329 + ProcessRsvpPathMessage (pRsvpPkt, InIfIndex, SourceIp, ttl);
46331 + else if (MsgType == PATH_TEAR_MSG)
46333 + ProcessRsvpPathTearMessage (pRsvpPkt, InIfIndex, SourceIp, ttl);
46334 + return;
46336 + else if (MsgType == RESV_MSG)
46338 + ProcessRsvpResvMessage (pRsvpPkt);
46340 + else if (MsgType == RESV_TEAR_MSG)
46342 + ProcessRsvpResvTearMessage (pRsvpPkt);
46344 + else if (MsgType == RESV_ERR_MSG)
46346 + ProcessRsvpResvErrMessage (pRsvpPkt);
46348 + else
46349 + zlog_err ("Unknown message type %d %s %d", MsgType, __FILE__,
46350 + __LINE__);
46352 + pFilterList = pFilterList->next;
46356 +E_RC
46357 +ResvTeMsgProc (TE_API_MSG * pMsg)
46359 + RSB_KEY RsbKey;
46360 + RSB *pRsb;
46361 + FILTER_LIST *pFilterList;
46362 + int i;
46363 + zlog_info ("response from TE");
46364 + memset (&RsbKey, 0, sizeof (RSB_KEY));
46365 + RsbKey = pMsg->u.ResvNotification.RsbKey;
46366 + zlog_info ("Session.Dest %x .TunnelId %x .ExtTunnelId %x",
46367 + RsbKey.Session.Dest,
46368 + RsbKey.Session.TunnelId, RsbKey.Session.ExtTunelId);
46369 + if ((pRsb =
46370 + (RSB *) patricia_tree_get (&ResbTree, (const uns8 *) &RsbKey)) == NULL)
46372 + zlog_err ("Cannot get RSB %x %x %x %s %d",
46373 + RsbKey.Session.Dest,
46374 + RsbKey.Session.TunnelId,
46375 + RsbKey.Session.ExtTunelId, __FILE__, __LINE__);
46376 + return E_ERR;
46378 + if (pMsg->u.ResvNotification.SharedExplicit)
46380 + for (i = 0;
46381 + i < pMsg->u.ResvNotification.u.FilterDataSE.FilterSpecNumber; i++)
46383 + pFilterList = pRsb->OldPacket.pFilterList;
46384 + while (pFilterList != NULL)
46386 + if (memcmp (&pFilterList->pFilterSpecData->FilterSpec,
46387 + &pMsg->u.ResvNotification.u.FilterDataSE.
46388 + FilterDataArraySE[i].FilterSpec,
46389 + sizeof (FILTER_SPEC_OBJ)) == 0)
46391 + zlog_info ("Found FilterSpec %x %x",
46392 + pFilterList->pFilterSpecData->FilterSpec.IpAddr,
46393 + pFilterList->pFilterSpecData->FilterSpec.LspId);
46394 + break;
46396 + pFilterList = pFilterList->next;
46398 + if ((pFilterList != NULL)
46399 + && (pFilterList->pFilterSpecData->pPsb->TE_InProcess == TRUE))
46401 + zlog_info ("Unlocking FilterSpec %x %x",
46402 + pFilterList->pFilterSpecData->FilterSpec.IpAddr,
46403 + pFilterList->pFilterSpecData->FilterSpec.LspId);
46404 + pFilterList->pFilterSpecData->pPsb->TE_InProcess = FALSE;
46408 + if (pMsg->u.ResvNotification.rc == FALSE)
46410 + if (pMsg->u.ResvNotification.SharedExplicit)
46412 + if (ProcessFailedSEFilterSpecsByIfIndex
46413 + (pRsb, pMsg->u.ResvNotification.u.FilterDataSE.IfIndex) != E_OK)
46415 + zlog_err
46416 + ("An error on ProcessForwardedSEFilterSpecsByIfIndex %s %d",
46417 + __FILE__, __LINE__);
46418 + return E_ERR;
46421 + else
46423 + if (ProcessFailedFFFilterSpec
46424 + (pRsb,
46425 + &pMsg->u.ResvNotification.u.FilterDataFF.FilterSpec) != E_OK)
46427 + zlog_err ("An error on ProcessForwardedFFFilterSpec %s %d",
46428 + __FILE__, __LINE__);
46429 + return E_ERR;
46432 + return E_OK;
46434 + if (pMsg->u.ResvNotification.SharedExplicit)
46436 + if (ProcessForwardedSEFilterSpecsByIfIndex
46437 + (pRsb, pMsg->u.ResvNotification.u.FilterDataSE.IfIndex) != E_OK)
46439 + zlog_err
46440 + ("An error on ProcessForwardedSEFilterSpecsByIfIndex %s %d",
46441 + __FILE__, __LINE__);
46442 + return E_ERR;
46445 + else
46447 + if (ProcessForwardedFFFilterSpec
46448 + (pRsb, &pMsg->u.ResvNotification.u.FilterDataFF.FilterSpec) != E_OK)
46450 + zlog_err ("An error on ProcessForwardedFFFilterSpec %s %d",
46451 + __FILE__, __LINE__);
46452 + return E_ERR;
46455 + RsbDequeueAndInvokeMessages (pRsb);
46456 + zlog_info ("done...");
46457 + return E_OK;
46460 +E_RC
46461 +FilterShutDown (FILTER_SPEC_DATA * pFilterSpecData, int Shared)
46463 + uns8 Priority;
46464 + zlog_info ("entering FilterShutDown");
46465 + if (pFilterSpecData == NULL)
46467 + zlog_err ("pFilterSpecData == NULL %s %d", __FILE__, __LINE__);
46468 + return E_ERR;
46471 + char buffer[80];
46472 + RSB *pRsb;
46473 + pRsb = pFilterSpecData->pPsb->pRsb;
46474 + sprintf (buffer, "Dest %x tunnel %x ext tunnel %x src %x lsp %x",
46475 + pRsb->RsbKey.Session.Dest,
46476 + pRsb->RsbKey.Session.TunnelId,
46477 + pRsb->RsbKey.Session.ExtTunelId,
46478 + pFilterSpecData->FilterSpec.IpAddr,
46479 + pFilterSpecData->FilterSpec.LspId);
46480 + zlog_info ("Session and filter: %s", buffer);
46482 + if (StopFilterAgeOutTimer (&pFilterSpecData->AgeOutTimer) != E_OK)
46484 + zlog_err ("Cannot delete timer %s %d", __FILE__, __LINE__);
46485 + return E_ERR;
46487 + if (StopBlocadeTimer (&pFilterSpecData->BlocadeTimer) != E_OK)
46489 + zlog_err ("Cannot delete timer %s %d", __FILE__, __LINE__);
46490 + return E_ERR;
46493 + if ((pFilterSpecData->pPsb->InIfIndex != 0) &&
46494 + (pFilterSpecData->pPHopResvRefreshList != NULL))
46496 + zlog_info ("Not Ingress...");
46498 + pFilterSpecData->pPHopResvRefreshList->MustBeProcessed = 1;
46499 + if (pFilterSpecData->pPHopResvRefreshList->pSentBuffer != NULL)
46501 + XFREE (MTYPE_RSVP,
46502 + pFilterSpecData->pPHopResvRefreshList->pSentBuffer);
46503 + pFilterSpecData->pPHopResvRefreshList->pSentBuffer = NULL;
46504 + pFilterSpecData->pPHopResvRefreshList->SentBufferLen = 0;
46507 + DeleteFilterListNode (&pFilterSpecData->pPHopResvRefreshList->
46508 + pFilterList, pFilterSpecData);
46510 + if (StopPHopResvRefreshTimer
46511 + (&pFilterSpecData->pPHopResvRefreshList->ResvRefreshTimer) != E_OK)
46513 + zlog_err ("Cannot delete timer %s %d", __FILE__, __LINE__);
46514 + return E_ERR;
46517 + if (pFilterSpecData->pPHopResvRefreshList->pFilterList == NULL)
46519 + if (DeletePHopResvRefreshList (pFilterSpecData->pPsb->pRsb,
46520 + pFilterSpecData->
46521 + pPHopResvRefreshList) != E_OK)
46523 + zlog_err ("Cannot delete PHopResvRefreshList item");
46527 +#if 0
46528 + else if (pFilterSpecData->pPsb->InIfIndex != 0)
46529 +#else
46530 + else if (pFilterSpecData->pPsb->pRsb != NULL)
46531 +#endif
46533 + zlog_info
46534 + ("PHopFilterList is NULL while not Ingress (TE may be in progress)");
46535 + PrepareAndSendResvTearNotificationMsg2TE (pFilterSpecData->pPsb->pRsb,
46536 + &pFilterSpecData->FilterSpec);
46538 + if (pFilterSpecData->pPsb->OutIfIndex != 0)
46540 + zlog_info ("Not Egress...");
46541 + if (Shared)
46543 + if (DeleteFilterListNode
46544 + (&pFilterSpecData->pEffectiveFlow->pFilterList,
46545 + pFilterSpecData) != E_OK)
46547 + zlog_err
46548 + ("Cannot delete filter from effective flow filter list");
46549 + return E_ERR;
46551 + if (pFilterSpecData->pEffectiveFlow->pFilterList == NULL)
46553 + if (pFilterSpecData->pPsb->OldPacket.SessionAttributes.CType ==
46554 + SESSION_ATTRIBUTES_RA_CLASS_TYPE)
46556 + Priority =
46557 + pFilterSpecData->pPsb->OldPacket.SessionAttributes.u.
46558 + SessAttrRa.HoldPrio;
46560 + else if (pFilterSpecData->pPsb->OldPacket.SessionAttributes.
46561 + CType == SESSION_ATTRIBUTES_CLASS_TYPE)
46563 + Priority =
46564 + pFilterSpecData->pPsb->OldPacket.SessionAttributes.u.
46565 + SessAttr.HoldPrio;
46567 + else
46569 + Priority = 4;
46571 + PrepareAndSendBWReleaseMsg2TE (pFilterSpecData->pPsb,
46572 + Priority,
46573 + pFilterSpecData->pEffectiveFlow->
46574 + IfIndex, Shared);
46575 + if (DeleteEffectiveFlow
46576 + (pFilterSpecData->pPsb->pRsb,
46577 + pFilterSpecData->pEffectiveFlow) != E_OK)
46579 + zlog_err ("Cannot delete effective flow list item");
46582 + else
46584 + pFilterSpecData->pEffectiveFlow->MustBeProcessed = 1;
46587 + else
46589 + if (pFilterSpecData->pPsb->OldPacket.SessionAttributes.CType ==
46590 + SESSION_ATTRIBUTES_RA_CLASS_TYPE)
46592 + Priority =
46593 + pFilterSpecData->pPsb->OldPacket.SessionAttributes.u.
46594 + SessAttrRa.HoldPrio;
46596 + else if (pFilterSpecData->pPsb->OldPacket.SessionAttributes.CType ==
46597 + SESSION_ATTRIBUTES_CLASS_TYPE)
46599 + Priority =
46600 + pFilterSpecData->pPsb->OldPacket.SessionAttributes.u.SessAttr.
46601 + HoldPrio;
46603 + else
46605 + Priority = 4;
46607 + /* update TE (BW release) */
46608 + PrepareAndSendBWReleaseMsg2TE (pFilterSpecData->pPsb,
46609 + Priority,
46610 + pFilterSpecData->pPsb->OutIfIndex,
46611 + Shared);
46614 + pFilterSpecData->pPsb->pRsb = NULL;
46615 + pFilterSpecData->pPsb->pFilterSpecData = NULL;
46616 + FreeFilterSpecData (&pFilterSpecData);
46617 + zlog_info ("leaving FilterShutDown");
46618 + return E_OK;
46621 +E_RC
46622 +ForwardResvTearMsg (RSB * pRsb)
46624 + RSVP_PKT RsvpPkt;
46625 + PHOP_RESV_REFRESH_LIST *pPHopResvRefreshList = pRsb->pPHopResvRefreshList;
46627 + zlog_info ("entering ForwardResvTearMsg");
46629 + memset (&RsvpPkt, 0, sizeof (RSVP_PKT));
46631 + RsvpPkt.Session = pRsb->RsbKey.Session;
46632 + RsvpPkt.pIntegrityObj = pRsb->OldPacket.pIntegrityObj;
46633 + RsvpPkt.pPolicyDataObj = pRsb->OldPacket.pPolicyDataObj;
46634 + RsvpPkt.Style = pRsb->OldPacket.Style;
46635 + while (pPHopResvRefreshList != NULL)
46637 + if (pPHopResvRefreshList->MustBeProcessed)
46639 + FILTER_LIST *pFilterList =
46640 + pPHopResvRefreshList->pFilterList, *pFilterListPrev = NULL;
46641 + while (pFilterList != NULL)
46643 + if (pFilterList->pFilterSpecData != NULL)
46645 + if (pFilterList->pFilterSpecData->ToBeDeleted)
46647 + if (pFilterListPrev == NULL)
46649 + pPHopResvRefreshList->pFilterList =
46650 + pPHopResvRefreshList->pFilterList->next;
46652 + else
46654 + pFilterListPrev->next = pFilterList->next;
46656 + pFilterList->next = RsvpPkt.pFilterList;
46657 + RsvpPkt.pFilterList = pFilterList;
46659 + else
46661 + pFilterListPrev = pFilterList;
46664 + pFilterList = pFilterList->next;
46666 + if (RsvpPkt.pFilterList != NULL)
46668 + if (pPHopResvRefreshList->InIfIndex != 0)
46670 + if (IpAddrGetByIfIndex
46671 + (pPHopResvRefreshList->InIfIndex,
46672 + &RsvpPkt.SentRsvpHop.PHop) != E_OK)
46674 + zlog_err ("Cannot set RSVP HOP %s %d", __FILE__,
46675 + __LINE__);
46676 + return E_ERR;
46678 + RsvpPkt.SentRsvpHop.LIH = pPHopResvRefreshList->PHop.LIH;
46679 + if (EncodeAndSendRsvpResvTearMessage (&RsvpPkt,
46680 + pPHopResvRefreshList->
46681 + PHop.PHop,
46682 + pPHopResvRefreshList->
46683 + InIfIndex, 1) != E_OK)
46685 + zlog_err ("cannot encode/send RESV_TEAR message");
46688 + else
46690 + zlog_info ("%s %d", __FILE__, __LINE__);
46692 + memset (&RsvpPkt.SentRsvpHop, 0, sizeof (RSVP_HOP_OBJ));
46693 + pFilterListPrev = RsvpPkt.pFilterList;
46694 + while (pFilterListPrev != NULL)
46696 + pFilterList = pFilterListPrev->next;
46697 + XFREE (MTYPE_RSVP, pFilterListPrev);
46698 + pFilterListPrev = pFilterList;
46700 + RsvpPkt.pFilterList = NULL;
46702 + //pPHopResvRefreshList->MustBeProcessed = 1;
46704 + pPHopResvRefreshList = pPHopResvRefreshList->next;
46706 + zlog_info ("leaving ForwardResvTearMsg");
46707 + return E_OK;
46710 +E_RC
46711 +ProcessRsvpResvTearMessage (RSVP_PKT * pRsvpPkt)
46713 + RSB *pRsb;
46714 + RSB_KEY RsbKey;
46715 + FILTER_SPEC_DATA *pFilterSpecData, *pFilterSpecData2;
46716 + FILTER_LIST *pFilterList, *pFilterListPrev =
46717 + NULL, *pFilterList2, *pFilterList2BeDeleted =
46718 + NULL, *pFilterListPrev2, *pFilterListNext;
46719 + uns8 ItemExtracted;
46720 + int Shared = 0;
46721 + zlog_info ("entering ProcessRsvpResvTearMessage");
46722 + RsvpStatistics.ResvTearMsgCount++;
46723 + memset (&RsbKey, 0, sizeof (RSB_KEY));
46724 + RsbKey.Session = pRsvpPkt->Session;
46726 + if ((pRsb = FindRsb (&RsbKey)) == NULL)
46728 + zlog_info ("leaving ProcessRsvpResvTearMessage");
46729 + FreeRsvpPkt (pRsvpPkt);
46730 + return E_OK;
46733 + if ((pRsb->OldPacket.Style.OptionVector2 & 0x001F) == SE_STYLE_BITS)
46735 + Shared = 1;
46737 + /* First - for the list of FILTER_SPECs to be deleted */
46738 + zlog_info ("Determining FilterSpecs to be deleted...");
46739 + pFilterList = pRsvpPkt->pFilterList;
46740 + while (pFilterList != NULL)
46742 + pFilterSpecData = pFilterList->pFilterSpecData;
46743 + pFilterListNext = pFilterList->next;
46744 + ItemExtracted = FALSE;
46745 + if (pFilterSpecData != NULL)
46747 + zlog_info ("FilterSpec %x %x", pFilterSpecData->FilterSpec.IpAddr,
46748 + pFilterSpecData->FilterSpec.LspId);
46749 + pFilterList2 = pRsb->OldPacket.pFilterList;
46750 + pFilterListPrev2 = NULL;
46751 + while (pFilterList2 != NULL)
46753 + pFilterSpecData2 = pFilterList2->pFilterSpecData;
46754 + if (pFilterSpecData2 != NULL)
46756 + zlog_info ("FilterSpec2 %x %x",
46757 + pFilterSpecData2->FilterSpec.IpAddr,
46758 + pFilterSpecData2->FilterSpec.LspId);
46759 + if (memcmp
46760 + (&pFilterSpecData->FilterSpec,
46761 + &pFilterSpecData2->FilterSpec,
46762 + sizeof (FILTER_SPEC_OBJ)) == 0)
46764 + if ((pFilterSpecData2->pPsb->TE_InProcess == TRUE) ||
46765 + ((pFilterSpecData2->pEffectiveFlow)
46766 + && (pFilterSpecData2->pEffectiveFlow->
46767 + TE_InProcess)))
46769 + RSVP_PKT_QUEUE *pQueuedItem;
46770 + RSVP_PKT *pSavedRsvpPkt;
46771 + if (pFilterListPrev == NULL)
46773 + pRsvpPkt->pFilterList = pFilterListNext;
46775 + else
46777 + pFilterListPrev->next = pFilterListNext;
46779 + ItemExtracted = TRUE;
46780 + if ((pSavedRsvpPkt =
46781 + (RSVP_PKT *) XMALLOC (MTYPE_RSVP,
46782 + sizeof (RSVP_PKT))) ==
46783 + NULL)
46785 + zlog_err ("memory allocation failed %s %d",
46786 + __FILE__, __LINE__);
46787 + return E_ERR;
46789 + memcpy (pSavedRsvpPkt, pRsvpPkt, sizeof (RSVP_PKT));
46790 + pSavedRsvpPkt->pFilterList = pFilterList;
46791 + pSavedRsvpPkt->pFilterList->next = NULL;
46792 + pSavedRsvpPkt->pIntegrityObj = NULL; /* temp. */
46793 + pSavedRsvpPkt->pPolicyDataObj = NULL; /* temp. */
46794 + pSavedRsvpPkt->pOpaqueObjList = NULL; /* temp. */
46795 + pSavedRsvpPkt->ReceivedRro.rr = NULL; /* TEMP!!! */
46796 + if ((pQueuedItem =
46797 + (RSVP_PKT_QUEUE *) XMALLOC (MTYPE_RSVP,
46798 + sizeof
46799 + (RSVP_PKT_QUEUE)))
46800 + == NULL)
46802 + zlog_err ("memory allocation failed %s %d",
46803 + __FILE__, __LINE__);
46804 + return E_ERR;
46807 + pQueuedItem->MsgType = RESV_TEAR_MSG;
46808 + pQueuedItem->pRsvpPkt = pSavedRsvpPkt;
46809 + pQueuedItem->next = NULL;
46810 + if (EnqueueRsvpPacket
46811 + (pQueuedItem,
46812 + &pFilterSpecData2->pPsb->packet_queue) != E_OK)
46814 + zlog_err ("Cannot enqueue packet %s %d",
46815 + __FILE__, __LINE__);
46816 + return E_ERR;
46818 + zlog_info ("Queued...");
46819 + break;
46821 + if (pFilterSpecData2->pPHopResvRefreshList != 0)
46823 + pFilterSpecData2->ToBeDeleted = 1;
46824 + pFilterSpecData2->pPHopResvRefreshList->
46825 + MustBeProcessed = 1;
46828 + if (pFilterListPrev2 == NULL)
46830 + pRsb->OldPacket.pFilterList =
46831 + pRsb->OldPacket.pFilterList->next;
46833 + else
46835 + pFilterListPrev2->next = pFilterList2->next;
46837 + pFilterList2->next = pFilterList2BeDeleted;
46838 + pFilterList2BeDeleted = pFilterList2;
46839 + zlog_info ("Inserted to deletion list...");
46840 + break;
46843 + else
46845 + zlog_info ("FilterSpec - FlowSpecData2 is NULL!!!");
46847 + pFilterListPrev2 = pFilterList2;
46848 + pFilterList2 = pFilterList2->next;
46851 + else
46853 + zlog_info ("FilterSpec - FlowSpecData is NULL!!!");
46855 + if (ItemExtracted == FALSE)
46857 + pFilterListPrev = pFilterList;
46859 + pFilterList = pFilterListNext;
46862 + if (ForwardResvTearMsg (pRsb) != E_OK)
46864 + zlog_err ("an error on ForwardResvTearMsg");
46867 + pFilterListPrev = pFilterList2BeDeleted;
46868 + while (pFilterListPrev != NULL)
46870 + PSB *pPsb;
46871 + pFilterList = pFilterListPrev->next;
46872 + pFilterSpecData = pFilterListPrev->pFilterSpecData;
46873 + pPsb = pFilterSpecData->pPsb;
46874 + if (FilterShutDown (pFilterSpecData, Shared) != E_OK)
46876 + zlog_err ("An error in FilterShutDown %s %d", __FILE__, __LINE__);
46878 + XFREE (MTYPE_RSVP, pFilterListPrev);
46879 + pFilterListPrev = pFilterList;
46882 + if ((pRsb->OldPacket.pFilterList == NULL) &&
46883 + ((pRsb->pEffectiveFlow != NULL) ||
46884 + (pRsb->pPHopResvRefreshList != NULL)))
46886 + zlog_err ("Cleanup was not completed properly %s %d", __FILE__,
46887 + __LINE__);
46890 + if (pRsb->OldPacket.pFilterList != NULL)
46892 + if (Shared)
46894 + if (ProcessEffectiveFlows (pRsb) != E_OK)
46896 + zlog_err ("An error in ProcessEffectiveFlows %s %d", __FILE__,
46897 + __LINE__);
46900 + /* update TE (BW release) */
46901 + if (ProcessPHopFilterSpecLists (pRsb, Shared) != E_OK)
46903 + zlog_err ("An error in ProcessPHopFilterSpecLists %s %d", __FILE__,
46904 + __LINE__);
46907 + else
46909 + FreeRSB (pRsb);
46911 + FreeRsvpPkt (pRsvpPkt);
46912 + zlog_info ("leaving ProcessRsvpResvTearMessage");
46913 + return E_OK;
46916 +typedef struct IfList
46918 + uns32 IfIndex;
46919 + IPV4_ADDR NHop;
46920 + uns8 ttl;
46921 + FILTER_LIST *pFilterList;
46922 + struct IfList *next;
46923 +} IF_LIST;
46925 +E_RC
46926 +ProcessRsvpResvErrMessage (RSVP_PKT * pRsvpPkt)
46928 + RSB *pRsb;
46929 + RSB_KEY RsbKey;
46930 + FILTER_LIST *pFilterList, *pFilterList2, *pFilterListNext,
46931 + *pFilterListPrev = NULL;
46932 + IF_LIST *pIfList = NULL, *pIfListEntry, *pIfListEntryPrev = NULL;
46933 + uns8 Shared = 0;
46934 + uns8 ItemExtracted;
46935 + RSVP_PKT RsvpPkt;
46936 + zlog_info ("entering ProcessRsvpResvErrMessage");
46937 + RsvpStatistics.ResvErrMsgCount++;
46938 + memset (&RsbKey, 0, sizeof (RSB_KEY));
46940 + RsbKey.Session = pRsvpPkt->Session;
46942 + if ((pRsb = FindRsb (&RsbKey)) == NULL)
46944 + zlog_err ("Cannot find RSB");
46945 + FreeRsvpPkt (pRsvpPkt);
46946 + return E_ERR;
46948 + if ((pRsb->OldPacket.Style.OptionVector2 & 0x001F) == SE_STYLE_BITS)
46950 + Shared = 1;
46953 + pFilterList = pRsvpPkt->pFilterList;
46954 + while (pFilterList != NULL)
46956 + FILTER_SPEC_DATA *pFilterSpecData = pFilterList->pFilterSpecData;
46957 + pFilterListNext = pFilterList->next;
46958 + ItemExtracted = FALSE;
46959 + if (pFilterSpecData == NULL)
46961 + pFilterList = pFilterList->next;
46962 + continue;
46964 + pFilterList2 = pRsb->OldPacket.pFilterList;
46965 + while (pFilterList2 != NULL)
46967 + if (pFilterList2->pFilterSpecData == NULL)
46969 + pFilterList2 = pFilterList2->next;
46970 + continue;
46972 + if ((pFilterSpecData->FilterSpec.IpAddr ==
46973 + pFilterList2->pFilterSpecData->FilterSpec.IpAddr)
46974 + && (pFilterSpecData->FilterSpec.LspId ==
46975 + pFilterList2->pFilterSpecData->FilterSpec.LspId))
46977 + if ((pFilterList2->pFilterSpecData->pPsb->TE_InProcess == TRUE)
46978 + || ((pFilterList2->pFilterSpecData->pEffectiveFlow)
46979 + && (pFilterList2->pFilterSpecData->pEffectiveFlow->
46980 + TE_InProcess == TRUE)))
46982 + RSVP_PKT_QUEUE *pQueuedItem;
46983 + RSVP_PKT *pSavedRsvpPkt;
46984 + if (pFilterListPrev == NULL)
46986 + pRsvpPkt->pFilterList = pFilterListNext;
46988 + else
46990 + pFilterListPrev->next = pFilterListNext;
46992 + ItemExtracted = TRUE;
46993 + if ((pSavedRsvpPkt =
46994 + (RSVP_PKT *) XMALLOC (MTYPE_RSVP,
46995 + sizeof (RSVP_PKT))) == NULL)
46997 + zlog_err ("memory allocation failed %s %d", __FILE__,
46998 + __LINE__);
46999 + return E_ERR;
47001 + memcpy (pSavedRsvpPkt, pRsvpPkt, sizeof (RSVP_PKT));
47002 + pSavedRsvpPkt->pFilterList = pFilterList;
47003 + pSavedRsvpPkt->pFilterList->next = NULL;
47004 + pSavedRsvpPkt->pIntegrityObj = NULL; /* temp. */
47005 + pSavedRsvpPkt->pPolicyDataObj = NULL; /* temp. */
47006 + pSavedRsvpPkt->pOpaqueObjList = NULL; /* temp. */
47007 + pSavedRsvpPkt->ReceivedRro.rr = NULL; /* TEMP!!! */
47008 + if ((pQueuedItem =
47009 + (RSVP_PKT_QUEUE *) XMALLOC (MTYPE_RSVP,
47010 + sizeof (RSVP_PKT_QUEUE)))
47011 + == NULL)
47013 + zlog_err ("memory allocation failed %s %d", __FILE__,
47014 + __LINE__);
47015 + return E_ERR;
47017 + pQueuedItem->MsgType = RESV_ERR_MSG;
47018 + pQueuedItem->pRsvpPkt = pSavedRsvpPkt;
47019 + pQueuedItem->next = NULL;
47020 + if (EnqueueRsvpPacket
47021 + (pQueuedItem,
47022 + &pFilterList2->pFilterSpecData->pPsb->packet_queue) !=
47023 + E_OK)
47025 + zlog_err ("Cannot enqueue packet %s %d", __FILE__,
47026 + __LINE__);
47027 + return E_ERR;
47029 + pFilterList2 = NULL;
47031 + break;
47033 + pFilterList2 = pFilterList2->next;
47035 + if (pFilterList2 != NULL)
47037 + uns32 IfIndex = pFilterList2->pFilterSpecData->pPsb->OutIfIndex;
47038 + IPV4_ADDR NHop = pFilterList2->pFilterSpecData->pPsb->NextHop;
47039 + uns8 ttl = pFilterList2->pFilterSpecData->pPsb->ttl;
47040 + if (IfIndex != 0)
47042 + pIfListEntry = pIfList;
47043 + while (pIfListEntry != NULL)
47045 + if (pIfListEntry->IfIndex == IfIndex)
47047 + break;
47049 + pIfListEntryPrev = pIfListEntry;
47050 + pIfListEntry = pIfListEntry->next;
47052 + if (pIfListEntry == NULL)
47054 + if ((pIfListEntry =
47055 + (IF_LIST *) XMALLOC (MTYPE_RSVP,
47056 + sizeof (IF_LIST))) == NULL)
47058 + zlog_err ("Cannot allocate memory %s %d", __FILE__,
47059 + __LINE__);
47060 + FreeRsvpPkt (pRsvpPkt);
47061 + return E_ERR;
47063 + memset (pIfListEntry, 0, sizeof (IF_LIST));
47064 + pIfListEntry->IfIndex = IfIndex;
47065 + pIfListEntry->NHop = NHop;
47066 + pIfListEntry->ttl = ttl;
47067 + if (pIfListEntryPrev == NULL)
47069 + pIfList = pIfListEntry;
47071 + else
47073 + pIfListEntryPrev->next = pIfListEntry;
47076 + if (NewFilterListNode
47077 + (&pIfListEntry->pFilterList, pFilterSpecData) != E_OK)
47079 + zlog_err ("An error on NewFilterListNode");
47080 + FreeRsvpPkt (pRsvpPkt);
47081 + return E_ERR;
47083 + if ((Shared) &&
47084 + (pRsvpPkt->ErrorSpec.ErrCode ==
47085 + ADMISSION_CTRL_FAILURE_ERR_CODE))
47087 + pFilterList2->pFilterSpecData->pEffectiveFlow->
47088 + MustBeProcessed = 1;
47091 + if (pRsvpPkt->ErrorSpec.ErrCode == ADMISSION_CTRL_FAILURE_ERR_CODE)
47093 + if (StartBlocadeTimer
47094 + (pFilterList2->pFilterSpecData->BlocadeValue,
47095 + &pFilterList2->pFilterSpecData->BlocadeTimer,
47096 + pFilterList2->pFilterSpecData) != E_OK)
47098 + zlog_err ("Cannot add timer");
47099 + FreeRsvpPkt (pRsvpPkt);
47100 + return E_ERR;
47102 + pFilterList2->pFilterSpecData->Blocked = TRUE;
47103 + memcpy (&pFilterList2->pFilterSpecData->BlockadeFlowSpec,
47104 + &pFilterList->pFilterSpecData->NewFlowSpec,
47105 + sizeof (FLOW_SPEC_OBJ));
47106 + if (pFilterList2->pFilterSpecData->pPsb->InIfIndex != 0)
47108 + pFilterList2->pFilterSpecData->pPHopResvRefreshList->
47109 + MustBeProcessed = 1;
47113 + if (ItemExtracted == FALSE)
47115 + pFilterListPrev = pFilterList;
47117 + pFilterList = pFilterListNext;
47119 + if (pRsvpPkt->ErrorSpec.ErrCode == ADMISSION_CTRL_FAILURE_ERR_CODE)
47121 + if (Shared)
47123 + if (ProcessEffectiveFlows (pRsb) != E_OK)
47125 + zlog_err ("An error on ProcessEffectiveFlows %s %d", __FILE__,
47126 + __LINE__);
47129 + else
47131 + pFilterList = pRsvpPkt->pFilterList;
47132 + while (pFilterList != NULL)
47134 + uns8 Priority;
47135 + if (pFilterList->pFilterSpecData->pPsb->OldPacket.
47136 + SessionAttributes.CType == SESSION_ATTRIBUTES_RA_CLASS_TYPE)
47138 + Priority =
47139 + pFilterList->pFilterSpecData->pPsb->OldPacket.
47140 + SessionAttributes.u.SessAttrRa.HoldPrio;
47142 + else if (pFilterList->pFilterSpecData->pPsb->OldPacket.
47143 + SessionAttributes.CType ==
47144 + SESSION_ATTRIBUTES_CLASS_TYPE)
47146 + Priority =
47147 + pFilterList->pFilterSpecData->pPsb->OldPacket.
47148 + SessionAttributes.u.SessAttr.HoldPrio;
47150 + else
47152 + Priority = 4;
47154 + PrepareAndSendBWReleaseMsg2TE (pFilterList->pFilterSpecData->
47155 + pPsb, Priority,
47156 + pFilterList->pFilterSpecData->
47157 + pPsb->OutIfIndex, Shared);
47158 + pFilterList = pFilterList->next;
47161 + if (ProcessPHopFilterSpecLists (pRsb, Shared) != E_OK)
47163 + zlog_err ("An error on ProcessPHopFilterSpecLists %s %d", __FILE__,
47164 + __LINE__);
47168 + pIfListEntry = pIfList;
47169 + memset (&RsvpPkt, 0, sizeof (RSVP_PKT));
47170 + RsvpPkt.Session = RsbKey.Session;
47171 + RsvpPkt.Style = pRsb->OldPacket.Style;
47172 + RsvpPkt.ErrorSpec = pRsvpPkt->ErrorSpec;
47173 + while (pIfListEntry != NULL)
47175 + RsvpPkt.SentRsvpHop.LIH = pIfListEntry->IfIndex;
47176 + if (IpAddrGetByIfIndex
47177 + (pIfListEntry->IfIndex, &RsvpPkt.SentRsvpHop.PHop) != E_OK)
47179 + zlog_err ("Cannot get IP address by IfIndex");
47180 + pIfListEntry = pIfListEntry->next;
47181 + continue;
47183 + RsvpPkt.pFilterList = pIfListEntry->pFilterList;
47184 + if (EncodeAndSendRsvpResvErrMessage
47185 + (&RsvpPkt, pIfListEntry->NHop, pIfListEntry->IfIndex,
47186 + pIfListEntry->ttl) != E_OK)
47188 + zlog_err ("An error on encode/send %s %d", __FILE__, __LINE__);
47190 + pFilterList = pIfListEntry->pFilterList;
47191 + while (pFilterList != NULL)
47193 + pFilterList2 = pFilterList->next;
47194 + XFREE (MTYPE_RSVP, pFilterList);
47195 + pFilterList = pFilterList2;
47197 + pIfList = pIfListEntry->next;
47198 + XFREE (MTYPE_RSVP, pIfListEntry);
47199 + pIfListEntry = pIfList;
47201 + FreeRsvpPkt (pRsvpPkt);
47202 + zlog_info ("leaving ProcessRsvpResvErrMessage");
47203 + return E_OK;
47206 +static void
47207 +PrepareAndSendBWReleaseMsg2TE (PSB * pPsb, uns8 Priority, uns32 IfIndex,
47208 + uns8 Shared)
47210 + TE_API_MSG msg;
47212 + memset (&msg, 0, sizeof (msg));
47213 + msg.NotificationType = BW_RELEASE_NOTIFICATION;
47214 + if (Shared)
47216 + msg.u.BwRelease.PsbKey.Session = pPsb->PsbKey.Session;
47218 + else
47220 + msg.u.BwRelease.PsbKey = pPsb->PsbKey;
47222 + msg.u.BwRelease.IfIndex = IfIndex;
47223 + msg.u.BwRelease.HoldPrio = Priority; /*pFilterSpecData->pPsb->OldPacket.SessionAttributes.u.SessAttrRa.HoldPrio */
47224 + zlog_info ("sending message to TE upon RESV");
47225 + rsvp_send_msg (&msg, sizeof (msg));
47228 +static void
47229 +PrepareAndSendResvTearNotificationMsg2TE (RSB * pRsb,
47230 + FILTER_SPEC_OBJ * pFilterSpec)
47232 + TE_API_MSG msg;
47234 + memset (&msg, 0, sizeof (msg));
47235 + msg.NotificationType = RESV_TEAR_NOTIFICATION;
47236 + msg.u.ResvTearNotification.RsbKey = pRsb->RsbKey;
47237 + msg.u.ResvTearNotification.FilterSpec = *pFilterSpec;
47238 + zlog_info ("sending message to TE upon RESV");
47239 + rsvp_send_msg (&msg, sizeof (msg));
47242 +void
47243 +PreemptFlow (TE_API_MSG * pMsg)
47245 + RSB *pRsb;
47246 + PSB *pPsb;
47247 + RSB_KEY RsbKey;
47248 + FILTER_LIST *pFilterList, *pFilterList2BeDeleted = NULL, *pFilterListPrev =
47249 + NULL;
47250 + RSVP_PKT RsvpPkt;
47251 + FILTER_SPEC_DATA *pFilterSpecData;
47252 + int Shared = 0;
47253 + IF_LIST *pIfList = NULL, *pIfListEntry, *pIfListEntryPrev = NULL;
47255 + zlog_info ("entering PreemptFlow");
47257 + memset (&RsbKey, 0, sizeof (RSB_KEY));
47258 + RsbKey = pMsg->u.PreemptFlow.RsbKey;
47259 + if ((pRsb = FindRsb (&RsbKey)) == NULL)
47261 + zlog_err ("Cannot find RSB %s %d", __FILE__, __LINE__);
47262 + return;
47264 + if ((pRsb->OldPacket.Style.OptionVector2 & 0x1F) == SE_STYLE_BITS)
47266 + Shared = 1;
47268 + memset (&RsvpPkt, 0, sizeof (RSVP_PKT));
47269 + RsvpPkt.Session = RsbKey.Session;
47270 + RsvpPkt.ErrorSpec.IpAddr = GetRouterId ();
47271 + RsvpPkt.ErrorSpec.ErrCode = ADMISSION_CTRL_FAILURE_ERR_CODE;
47272 + RsvpPkt.ErrorSpec.ErrVal = BW_UNAVAILABLE;
47273 + pFilterList = pRsb->OldPacket.pFilterList;
47274 + if (!pMsg->u.PreemptFlow.FilterSpecValid)
47276 + pFilterList2BeDeleted = pFilterList;
47277 + pRsb->OldPacket.pFilterList = NULL;
47279 + while (pFilterList != NULL)
47281 + pFilterSpecData = pFilterList->pFilterSpecData;
47282 + if (((pMsg->u.PreemptFlow.FilterSpecValid) &&
47283 + (memcmp (&pFilterSpecData->FilterSpec,
47284 + &pMsg->u.PreemptFlow.FilterSpec,
47285 + sizeof (FILTER_SPEC_OBJ)) == 0)) ||
47286 + (!pMsg->u.PreemptFlow.FilterSpecValid))
47288 + uns32 IfIndex = pFilterSpecData->pPsb->OutIfIndex;
47289 + IPV4_ADDR NHop = pFilterSpecData->pPsb->NextHop;
47290 + uns8 ttl = pFilterSpecData->pPsb->ttl;
47292 + if (IfIndex != 0)
47294 + pIfListEntry = pIfList;
47295 + while (pIfListEntry != NULL)
47297 + if (pIfListEntry->IfIndex == IfIndex)
47298 + break;
47299 + pIfListEntryPrev = pIfListEntry;
47300 + pIfListEntry = pIfListEntry->next;
47302 + if (pIfListEntry == NULL)
47304 + if ((pIfListEntry =
47305 + (IF_LIST *) XMALLOC (MTYPE_RSVP,
47306 + sizeof (IF_LIST))) == NULL)
47308 + zlog_err ("Cannot allocate memory %s %d", __FILE__,
47309 + __LINE__);
47310 + return;
47312 + memset (pIfListEntry, 0, sizeof (IF_LIST));
47313 + pIfListEntry->IfIndex = IfIndex;
47314 + pIfListEntry->NHop = NHop;
47315 + pIfListEntry->ttl = ttl;
47316 + if (NewFilterListNode
47317 + (&pIfListEntry->pFilterList, pFilterSpecData) != E_OK)
47319 + zlog_err ("An error on NewFilterListNode");
47320 + return;
47322 + if (pIfListEntryPrev == NULL)
47324 + pIfList = pIfListEntry;
47326 + else
47328 + pIfListEntryPrev->next = pIfListEntry;
47331 + if (Shared)
47333 + pFilterSpecData->pEffectiveFlow->MustBeProcessed = 1;
47337 + if (pFilterSpecData->pPsb->InIfIndex != 0)
47339 + if (GeneratePathErrMessage
47340 + (pFilterSpecData->pPsb, POLICY_CTRL_FAILURE_ERR_CODE,
47341 + 0) != E_OK)
47343 + zlog_err ("Cannot encode/send PathErr message %s %d",
47344 + __FILE__, __LINE__);
47346 + pFilterSpecData->pPHopResvRefreshList->MustBeProcessed = 1;
47349 + if (pMsg->u.PreemptFlow.FilterSpecValid)
47351 + if (pFilterListPrev == NULL)
47353 + pRsb->OldPacket.pFilterList =
47354 + pRsb->OldPacket.pFilterList->next;
47356 + else
47358 + pFilterListPrev->next = pFilterList->next;
47360 + pFilterList->next = pFilterList2BeDeleted;
47361 + pFilterList2BeDeleted = pFilterList;
47362 + break;
47365 + pFilterListPrev = pFilterList;
47366 + pFilterList = pFilterList->next;
47368 + memset (&RsvpPkt, 0, sizeof (RSVP_PKT));
47369 + RsvpPkt.Session = RsbKey.Session;
47370 + RsvpPkt.Style = pRsb->OldPacket.Style;
47371 + pIfListEntry = pIfList;
47372 + while (pIfListEntry != NULL)
47374 + RsvpPkt.pFilterList = pIfListEntry->pFilterList;
47375 + if (EncodeAndSendRsvpResvErrMessage (&RsvpPkt,
47376 + pIfListEntry->NHop,
47377 + pIfListEntry->IfIndex,
47378 + pIfListEntry->ttl) != E_OK)
47380 + zlog_err ("Cannot encode/send ResvErr message %s %d", __FILE__,
47381 + __LINE__);
47383 + pIfListEntry = pIfListEntry->next;
47385 + pIfListEntry = pIfList;
47386 + while (pIfListEntry != NULL)
47388 + pFilterListPrev = pIfListEntry->pFilterList;
47389 + while (pFilterListPrev != NULL)
47391 + pFilterList = pFilterListPrev->next;
47392 + XFREE (MTYPE_RSVP, pFilterListPrev);
47393 + pFilterListPrev = pFilterList;
47395 + pIfList = pIfListEntry->next;
47396 + XFREE (MTYPE_RSVP, pIfListEntry);
47397 + pIfListEntry = pIfList;
47399 + pFilterListPrev = pFilterList2BeDeleted;
47400 + while (pFilterListPrev != NULL)
47402 + pFilterList = pFilterListPrev->next;
47403 + pFilterSpecData = pFilterListPrev->pFilterSpecData;
47404 + pPsb = pFilterSpecData->pPsb;
47405 + if (FilterShutDown (pFilterSpecData, Shared) != E_OK)
47407 + zlog_err ("An error in FilterShutDown %s %d", __FILE__, __LINE__);
47409 + if (DeletePsb (pPsb) != E_OK)
47411 + zlog_err ("Cannot delete PSB %s %d", __FILE__, __LINE__);
47413 + XFREE (MTYPE_RSVP, pFilterListPrev);
47414 + pFilterListPrev = pFilterList;
47417 + if (pRsb->OldPacket.pFilterList != NULL)
47419 + if (Shared)
47421 + if (ProcessEffectiveFlows (pRsb) != E_OK)
47423 + zlog_err ("An error in ProcessEffectiveFlows %s %d", __FILE__,
47424 + __LINE__);
47427 + /* update TE (BW release) */
47428 + if (ProcessPHopFilterSpecLists (pRsb, Shared) != E_OK)
47430 + zlog_err ("An error in ProcessPHopFilterSpecLists %s %d", __FILE__,
47431 + __LINE__);
47434 + else
47436 + FreeRSB (pRsb);
47438 + zlog_info ("leaving PreemptFlow");
47440 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_rsb.h quagga-mpls/rsvpd/rsvp_rsb.h
47441 --- quagga/rsvpd/rsvp_rsb.h 1969-12-31 18:00:00.000000000 -0600
47442 +++ quagga-mpls/rsvpd/rsvp_rsb.h 2007-06-14 21:35:58.000000000 -0500
47443 @@ -0,0 +1,62 @@
47445 +#ifndef __RSVP_RSB_H_
47446 +#define __RSVP_RSB_H_
47448 +typedef struct _phop_resv_refresh_list_
47450 + RSVP_HOP_OBJ PHop;
47451 + uns32 InIfIndex;
47452 + uns32 RefreshValue;
47453 + struct thread *ResvRefreshTimer;
47454 + FILTER_LIST *pFilterList;
47455 + RR_SUBOBJ *pAddedRro;
47456 + FLOW_SPEC_OBJ FwdFlowSpec; /* for SE only */
47457 + uns8 MustBeProcessed;
47458 + char *pSentBuffer;
47459 + uns16 SentBufferLen;
47460 + struct _phop_resv_refresh_list_ *next;
47461 +} PHOP_RESV_REFRESH_LIST;
47463 +typedef struct _effective_flow_
47465 + uns32 IfIndex;
47466 + FLOW_SPEC_OBJ CurrentFlowSpec;
47467 + uns8 MustBeProcessed; /* indicates that list of corresponding filters was changed */
47468 + FLOW_SPEC_OBJ NewFlowSpec;
47469 + FILTER_LIST *pFilterList;
47470 + uns8 TE_InProcess;
47471 + struct _effective_flow_ *next;
47472 +} EFFECTIVE_FLOW;
47474 +typedef struct _rsb_
47476 + PATRICIA_NODE Node;
47477 + RSB_KEY RsbKey;
47478 + RSVP_PKT OldPacket;
47479 + uns8 ResvRefreshFlag;
47480 + PHOP_RESV_REFRESH_LIST *pPHopResvRefreshList;
47481 + EFFECTIVE_FLOW *pEffectiveFlow; /* for SE only */
47482 +} RSB;
47484 +struct _te_api_msg_;
47486 +RSB *FindRsb (RSB_KEY * pRsbKey);
47487 +RSB *GetNextRSB (RSB_KEY * pRsbKey);
47488 +E_RC ProcessEffectiveFlows (RSB * pRsb);
47489 +E_RC ProcessPHopFilterSpecLists (RSB * pRsb, uns8 Shared);
47490 +E_RC FilterShutDown (FILTER_SPEC_DATA * pFilterSpecData, int Shared);
47491 +E_RC ProcessRsvpResvTearMessage (RSVP_PKT * pRsvpPkt);
47492 +E_RC ProcessRsvpResvErrMessage (RSVP_PKT * pRsvpPkt);
47493 +E_RC ProcessRsvpResvMessage (RSVP_PKT * pRsvpPkt);
47494 +E_RC NewFilterListNode (FILTER_LIST ** ppFilterListHead,
47495 + FILTER_SPEC_DATA * pFilterSpecData);
47496 +E_RC ForwardResvTearMsg (RSB * pRsb);
47497 +E_RC NewModifiedPath (PSB * pPsb);
47498 +E_RC InitResvProcessing ();
47499 +E_RC ResvTeMsgProc (struct _te_api_msg_ *pMsg);
47500 +void PreemptFlow (struct _te_api_msg_ *pMsg);
47501 +E_RC RemoveRSB (RSB_KEY * pRsbKey);
47502 +E_RC DeleteFilterListNode (FILTER_LIST ** ppFilterList,
47503 + FILTER_SPEC_DATA * pFilterSpecData);
47505 +#endif
47506 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_socket.c quagga-mpls/rsvpd/rsvp_socket.c
47507 --- quagga/rsvpd/rsvp_socket.c 1969-12-31 18:00:00.000000000 -0600
47508 +++ quagga-mpls/rsvpd/rsvp_socket.c 2007-07-02 22:50:59.000000000 -0500
47509 @@ -0,0 +1,429 @@
47510 +/* Module: rsvp_socket.c
47511 + Contains: RSVP socket routines
47512 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
47513 + */
47514 +#include "rsvp.h"
47515 +#include "if.h"
47517 +typedef struct
47519 + PATRICIA_NODE Node;
47520 + uns32 IfIndex;
47521 + int IfSocket;
47522 + IPV4_ADDR IpAddr;
47523 + IPV4_ADDR Peer;
47524 + char IfName[20];
47525 + struct thread *pThread;
47526 +} IF_NODE;
47528 +PATRICIA_TREE IfTree;
47530 +char BigBuf[1024];
47532 +extern struct thread_master *master;
47535 +E_RC
47536 +IpAddrGetByIfIndex (uns32 IfIndex, IPV4_ADDR * pIpAddr)
47538 + IF_NODE *pIfNode;
47540 + if ((pIfNode =
47541 + (IF_NODE *) patricia_tree_get (&IfTree,
47542 + (const uns8 *) &IfIndex)) == NULL)
47544 + zlog_err ("cannot get a node from patricia tree %s %d", __FILE__,
47545 + __LINE__);
47546 + return E_ERR;
47548 + *pIpAddr = pIfNode->IpAddr;
47549 + return E_OK;
47552 +E_RC
47553 +IpAddrSetByIfIndex (uns32 IfIndex, IPV4_ADDR IpAddr)
47555 + IF_NODE *pIfNode;
47557 + if ((pIfNode =
47558 + (IF_NODE *) patricia_tree_get (&IfTree,
47559 + (const uns8 *) &IfIndex)) == NULL)
47561 + if ((pIfNode =
47562 + (IF_NODE *) XMALLOC (MTYPE_RSVP, sizeof (IF_NODE))) == NULL)
47564 + zlog_err ("cannot allocate memory %s %d", __FILE__, __LINE__);
47565 + return E_ERR;
47567 + memset (pIfNode, 0, sizeof (IF_NODE));
47568 + pIfNode->IfIndex = IfIndex;
47569 + pIfNode->Node.key_info = (uns8 *) & pIfNode->IfIndex;
47570 + if (patricia_tree_add (&IfTree, (PATRICIA_NODE *) & pIfNode->Node) !=
47571 + E_OK)
47573 + zlog_err ("cannot add node to patricia");
47574 + return E_ERR;
47577 + pIfNode->IpAddr = IpAddr;
47578 + return E_OK;
47581 +E_RC
47582 +InitInterfaceDB ()
47584 + PATRICIA_PARAMS params;
47586 + memset (&params, 0, sizeof (PATRICIA_PARAMS));
47587 + params.key_size = sizeof (uns32);
47588 + if (patricia_tree_init (&IfTree, &params) != E_OK)
47590 + zlog_err ("cannot initiate I/F patricia tree");
47591 + return E_ERR;
47593 + return E_OK;
47596 +E_RC
47597 +SetRouterAlert (int sock)
47599 +#if defined(IPOPT_RA)
47600 + static const char ra_opt[4] = { IPOPT_RA, 4, 0, 0 };
47603 + if (setsockopt (sock, IPPROTO_IP, IP_OPTIONS, ra_opt, sizeof (ra_opt)))
47605 + zlog_err ("Cannot set router alert %s %s %d", strerror (errno),
47606 + __FILE__, __LINE__);
47607 + return E_ERR;
47609 +#endif /* defined(IPOPT_RA) */
47610 + return E_OK;
47613 +E_RC
47614 +SetTtl (int sock, uns16 ttl)
47616 + uns16 multicast = (uns16) (ttl & 0x8000); /* most significant bit indicates multicast */
47617 + int set_ttl = (int) (ttl & 0x00FF);
47619 + /* specify the ttl value for subsequent datagrams sent out on this socket */
47621 +#ifdef IP_TTL
47623 + if (multicast == 0)
47624 + if (setsockopt
47625 + (sock, IPPROTO_IP, IP_TTL, (char *) &set_ttl,
47626 + sizeof (set_ttl)) != 0)
47628 + zlog_err ("Cannot set ttl %s %s %d", strerror (errno), __FILE__,
47629 + __LINE__);
47630 + return E_ERR;
47633 +#endif
47636 + /* specify the ttl for multicast messages sent out on this socket */
47638 +#ifdef IP_MULTICAST_TTL
47640 + if (multicast == 0x8000)
47641 + if (setsockopt
47642 + (sock, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &set_ttl,
47643 + sizeof (set_ttl)) != 0)
47645 + zlog_err ("Cannot set ttl %s %s %d", strerror (errno), __FILE__,
47646 + __LINE__);
47647 + return E_ERR;
47650 +#endif
47652 + return E_OK;
47655 +E_RC
47656 +SendRawData (char *buffer, uns32 Len, IPV4_ADDR remote_addr, uns32 IfIndex,
47657 + uns8 ttl, uns8 RouterAlert)
47659 + struct sockaddr_in saddr;
47660 + int bytes_sent;
47661 + IF_NODE *pIfNode;
47662 + zlog_info ("entering SendRawData");
47663 + if ((pIfNode =
47664 + (IF_NODE *) patricia_tree_get (&IfTree,
47665 + (const uns8 *) &IfIndex)) == NULL)
47667 + zlog_err ("Cannot get node from patricia tree, IfIndex %d %s %d",
47668 + IfIndex, __FILE__, __LINE__);
47669 + return E_ERR;
47672 + memset ((char *) &saddr, 0x00, sizeof (saddr));
47673 + saddr.sin_family = AF_INET;
47674 + saddr.sin_addr.s_addr = remote_addr;
47677 + if (SetTtl (pIfNode->IfSocket, ttl) != E_OK)
47679 + zlog_err ("Cannot set ttl");
47682 + if (RouterAlert == TRUE)
47684 + if (SetRouterAlert (pIfNode->IfSocket) != E_OK)
47686 + zlog_err ("Cannot set router alert");
47690 + bytes_sent =
47691 + sendto (pIfNode->IfSocket, buffer, Len, 0, (struct sockaddr *) &saddr,
47692 + sizeof (saddr));
47693 + if (bytes_sent == -1)
47695 + zlog_err ("an error occured on sendto %s", strerror (errno));
47696 + return E_ERR;
47698 + else if (bytes_sent < Len)
47700 + zlog_err ("tried to send %d bytes, actually sent %d", Len, bytes_sent);
47701 + return E_ERR;
47703 + zlog_info ("leaving SendRawData");
47704 + return E_OK;
47707 +int
47708 +ProcessRsvpMsg (struct thread *pThread)
47710 + int FromLen, PktLen;
47711 + IF_NODE *pIfNode;
47712 + struct sockaddr_in from;
47713 + uns8 *pIpHdr;
47715 + pIfNode = pThread->arg;
47717 + memset (&from, 0, sizeof (struct sockaddr_in));
47718 + FromLen = sizeof (struct sockaddr_in);
47719 + from.sin_family = AF_INET;
47721 + if (ioctl (pIfNode->IfSocket, FIONREAD, &PktLen) < 0)
47723 + zlog_err (" an error %s on ioctl %s %d", strerror (errno), __FILE__,
47724 + __LINE__);
47726 + zlog_info ("message received on %d %s", pIfNode->IfIndex, pIfNode->IfName);
47727 + memset (BigBuf, 0, 1000);
47728 + if ((PktLen =
47729 + recvfrom (pIfNode->IfSocket, BigBuf, 1000, 0,
47730 + (struct sockaddr *) &from, &FromLen)) < 0)
47732 + zlog_err ("an error occured on recvfrom %s %s",
47733 + pIfNode->IfName, strerror (errno));
47735 + else
47737 + zlog_info ("From %x", from.sin_addr.s_addr);
47738 + pIpHdr = BigBuf;
47739 + PktLen -= (unsigned int) 4 *(*pIpHdr & 0xf);
47740 + DecodeAndProcessRsvpMsg (&BigBuf[(unsigned int) 4 * (*pIpHdr & 0xf)],
47741 + PktLen, pIfNode->IfIndex, 0);
47743 + pIfNode->pThread =
47744 + thread_add_read (master, ProcessRsvpMsg, pIfNode, pIfNode->IfSocket);
47745 + return 0;
47748 +E_RC
47749 +IsRsvpEnabledOnIf (int IfIndex)
47751 + IF_NODE *pIfNode;
47753 + if ((pIfNode =
47754 + (IF_NODE *) patricia_tree_get (&IfTree,
47755 + (const uns8 *) &IfIndex)) == NULL)
47757 + zlog_err ("Cannot get node from patricia tree, IfIndex %d %s %d",
47758 + IfIndex, __FILE__, __LINE__);
47759 + return E_ERR;
47761 + if (pIfNode->IfSocket)
47763 + return E_OK;
47765 + return E_ERR;
47768 +E_RC
47769 +EnableRsvpOnInterface2 (int IfIndex)
47771 + struct sockaddr_in saddr;
47772 + IF_NODE *pIfNode;
47774 + if ((pIfNode =
47775 + (IF_NODE *) patricia_tree_get (&IfTree,
47776 + (const uns8 *) &IfIndex)) == NULL)
47778 + zlog_err ("cannot get a node from patricia");
47779 + return E_ERR;
47782 + memset (&saddr, 0x00, sizeof (saddr));
47783 + saddr.sin_family = AF_INET;
47784 + /*saddr.sin_port = htons(0); */
47785 + saddr.sin_addr.s_addr = htonl (pIfNode->IpAddr);
47786 + if (bind
47787 + (pIfNode->IfSocket, (struct sockaddr *) &saddr,
47788 + sizeof (struct sockaddr_in)) < 0)
47790 + zlog_err ("cannot bind socket (%s) for %s %s %d",
47791 + strerror (errno), pIfNode->IfName, __FILE__, __LINE__);
47792 + return E_ERR;
47795 + char str1[16];
47796 + sprintf (str1, "%x", pIfNode->IpAddr);
47797 + zlog_info ("Upon enabling RSVP on I/F %s %s %d",
47798 + pIfNode->IfName, str1, pIfNode->IfSocket);
47800 + if (pIfNode->pThread == NULL)
47801 + pIfNode->pThread =
47802 + thread_add_read (master, ProcessRsvpMsg, pIfNode, pIfNode->IfSocket);
47803 + return E_OK;
47806 +E_RC
47807 +EnableRsvpOnInterface (uns32 IfIndex)
47809 + static const unsigned int bio = 1;
47810 + static const int smode = 1;
47811 + IF_NODE *pIfNode;
47812 + struct interface *ifp = NULL;
47814 + int sock = socket (AF_INET, SOCK_RAW, RSVP_IP_PROTOCOL);
47816 + if ((pIfNode =
47817 + (IF_NODE *) patricia_tree_get (&IfTree,
47818 + (const uns8 *) &IfIndex)) == NULL)
47820 + if ((pIfNode =
47821 + (IF_NODE *) XMALLOC (MTYPE_RSVP, sizeof (IF_NODE))) == NULL)
47823 + zlog_err ("cannot allocate memory %s %d", __FILE__, __LINE__);
47824 + return E_ERR;
47826 + memset (pIfNode, 0, sizeof (IF_NODE));
47827 + pIfNode->IfIndex = IfIndex;
47828 + pIfNode->Node.key_info = (uns8 *) & pIfNode->IfIndex;
47829 + if (patricia_tree_add (&IfTree, (PATRICIA_NODE *) & pIfNode->Node) !=
47830 + E_OK)
47832 + zlog_err ("cannot add node to patricia");
47833 + return E_ERR;
47837 + if (sock < 0)
47839 + zlog_err ("cannot open socket %s %s %d", strerror (errno), __FILE__,
47840 + __LINE__);
47841 + return E_ERR;
47844 + if (ioctl (sock, FIONBIO, &bio) < 0)
47846 + zlog_err ("cannot set non blocking mode for I/F %d %s %d", IfIndex,
47847 + __FILE__, __LINE__);
47848 + return E_ERR;
47851 + if (setsockopt
47852 + (sock, SOL_SOCKET, SO_REUSEADDR, (char *) &smode, sizeof (smode)))
47854 + zlog_err ("cannot set reuse address option for I/F %d %s %d", IfIndex,
47855 + __FILE__, __LINE__);
47856 + return E_ERR;
47858 + ifp = if_lookup_by_index (IfIndex);
47859 + strncpy (pIfNode->IfName, ifp->name, INTERFACE_NAMSIZ);
47860 +#if 1
47862 + /** Build a ifreq to get mapping of device index to name,
47863 + ** since the bind to device sockopt operates on name.
47864 + **/
47865 + struct ifreq ifr;
47866 + memset (&ifr, '\0', sizeof ifr);
47868 + strcpy (ifr.ifr_name, pIfNode->IfName);
47870 + if (setsockopt
47871 + (sock, SOL_SOCKET, SO_BINDTODEVICE, ifr.ifr_name, IFNAMSIZ))
47873 + zlog_err ("cannot set bind to device option for %s %s %d",
47874 + pIfNode->IfName, __FILE__, __LINE__);
47875 + return E_ERR;
47878 +#endif
47879 +#if 0
47881 + int ra = 0, Len = sizeof (ra);
47882 + static const int ra_true = 1;
47883 + if (setsockopt
47884 + (sock, /*IPPROTO_IP */ SOL_SOCKET, IP_ROUTER_ALERT, &ra_true,
47885 + sizeof (ra_true)) != 0)
47887 + zlog_err ("cannot set router alert option for %s %s %d", IfName,
47888 + __FILE__, __LINE__);
47889 + return E_ERR;
47891 + if (getsockopt (sock, SOL_SOCKET, IP_ROUTER_ALERT, &ra, &Len) != 0)
47893 + zlog_err ("cannot get router alert option for %s error %s %s %d",
47894 + IfName, strerror (errno), __FILE__, __LINE__);
47895 + return E_ERR;
47897 + else
47899 + printf ("ROUTER ALERT %x\n", ra);
47902 +#endif
47904 + pIfNode->IfSocket = sock;
47905 + if (pIfNode->IpAddr != 0)
47907 + return EnableRsvpOnInterface2 (IfIndex);
47909 + else
47911 + return E_OK;
47915 +E_RC
47916 +DisableRsvpOnInterface (int IfIndex)
47918 + IF_NODE *pIfNode;
47920 + if ((pIfNode =
47921 + (IF_NODE *) patricia_tree_get (&IfTree,
47922 + (const uns8 *) &IfIndex)) == NULL)
47924 + zlog_err ("cannot get a node from patricia");
47925 + return E_ERR;
47927 + if (pIfNode->pThread)
47928 + thread_cancel (pIfNode->pThread);
47929 + pIfNode->pThread = NULL;
47930 + close (pIfNode->IfSocket);
47931 + if (patricia_tree_del (&IfTree, (PATRICIA_NODE *) & pIfNode->Node) != E_OK)
47933 + zlog_err ("cannot del node from patricia");
47934 + return E_ERR;
47936 + XFREE (MTYPE_RSVP, pIfNode);
47937 + return E_OK;
47939 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_socket.h quagga-mpls/rsvpd/rsvp_socket.h
47940 --- quagga/rsvpd/rsvp_socket.h 1969-12-31 18:00:00.000000000 -0600
47941 +++ quagga-mpls/rsvpd/rsvp_socket.h 2007-06-14 21:35:58.000000000 -0500
47942 @@ -0,0 +1,17 @@
47944 +#ifndef __RSVP_SOCKET_H_
47945 +#define __RSVP_SOCKET_H_
47947 +E_RC EnableRsvpOnInterface (uns32 IfIndex);
47948 +E_RC EnableRsvpOnInterface2 (int IfIndex);
47949 +E_RC DisableRsvpOnInterface (int IfIndex);
47950 +int ProcessRsvpMsg (struct thread *pThread);
47951 +E_RC IpAddrGetByIfIndex (uns32 IfIndex, IPV4_ADDR * pIpAddr);
47952 +E_RC IpAddrSetByIfIndex (uns32 IfIndex, IPV4_ADDR IpAddr);
47953 +E_RC IsRsvpEnabledOnIf (int IfIndex);
47954 +E_RC SendRawData (char *buffer,
47955 + uns32 Len,
47956 + IPV4_ADDR remote_addr,
47957 + uns32 IfIndex, uns8 ttl, uns8 RouterAlert);
47958 +E_RC InitInterfaceDB ();
47959 +#endif
47960 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_utilities.c quagga-mpls/rsvpd/rsvp_utilities.c
47961 --- quagga/rsvpd/rsvp_utilities.c 1969-12-31 18:00:00.000000000 -0600
47962 +++ quagga-mpls/rsvpd/rsvp_utilities.c 2007-07-02 22:50:59.000000000 -0500
47963 @@ -0,0 +1,985 @@
47964 +/* Module: rsvp_utilities.c
47965 + Contains: RSVP utilities - object allocation and freeing,
47966 + dump etc.
47967 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
47968 + */
47969 +#include "rsvp.h"
47972 +#define LOG1(a1) \
47974 + if(vty) \
47975 + {\
47976 + vty_out(vty,a1);\
47977 + vty_out(vty,"%s",VTY_NEWLINE);\
47978 + }\
47979 + else \
47980 + {\
47981 + zlog_info(a1);\
47982 + }\
47985 +#define LOG2(a1,a2) \
47987 + if(vty) \
47988 + {\
47989 + vty_out(vty,a1,a2);\
47990 + vty_out(vty,"%s",VTY_NEWLINE);\
47991 + }\
47992 + else \
47993 + {\
47994 + zlog_info(a1,a2);\
47995 + }\
47998 +#define LOG3(a1,a2,a3) \
48000 + if(vty) \
48001 + {\
48002 + vty_out(vty,a1,a2,a3);\
48003 + vty_out(vty,"%s",VTY_NEWLINE);\
48004 + }\
48005 + else \
48006 + {\
48007 + zlog_info(a1,a2,a3);\
48008 + }\
48011 +#define LOG4(a1,a2,a3,a4) \
48013 + if(vty) \
48014 + {\
48015 + vty_out(vty,a1,a2,a3,a4);\
48016 + vty_out(vty,"%s",VTY_NEWLINE);\
48017 + }\
48018 + else \
48019 + {\
48020 + zlog_info(a1,a2,a3,a4);\
48021 + }\
48024 +#define LOG5(a1,a2,a3,a4,a5) \
48026 + if(vty) \
48027 + {\
48028 + vty_out(vty,a1,a2,a3,a4,a5);\
48029 + vty_out(vty,"%s",VTY_NEWLINE);\
48030 + }\
48031 + else \
48032 + {\
48033 + zlog_info(a1,a2,a3,a4,a5);\
48034 + }\
48037 +#define LOG6(a1,a2,a3,a4,a5,a6) \
48039 + if(vty) \
48040 + {\
48041 + vty_out(vty,a1,a2,a3,a4,a5,a6);\
48042 + vty_out(vty,"%s",VTY_NEWLINE);\
48043 + }\
48044 + else \
48045 + {\
48046 + zlog_info(a1,a2,a3,a4,a5,a6);\
48047 + }\
48050 +#define LOG7(a1,a2,a3,a4,a5,a6,a7) \
48052 + if(vty) \
48053 + {\
48054 + vty_out(vty,a1,a2,a3,a4,a5,a6,a7);\
48055 + vty_out(vty,"%s",VTY_NEWLINE);\
48056 + }\
48057 + else \
48058 + {\
48059 + zlog_info(a1,a2,a3,a4,a5,a6,a7);\
48060 + }\
48063 +#define LOG8(a1,a2,a3,a4,a5,a6,a7,a8) \
48065 + if(vty) \
48066 + {\
48067 + vty_out(vty,a1,a2,a3,a4,a5,a6,a7,a8);\
48068 + vty_out(vty,"%s",VTY_NEWLINE);\
48069 + }\
48070 + else \
48071 + {\
48072 + zlog_info(a1,a2,a3,a4,a5,a6,a7,a8);\
48073 + }\
48076 +RSVP_STATISTICS RsvpStatistics = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
48078 +typedef struct
48080 + PATRICIA_NODE Node;
48081 + IPV4_ADDR IfIpAddress;
48082 + uns8 PrefixLen;
48083 +} IF_IP_NODE;
48085 +static PATRICIA_TREE IfIpAddressesTree;
48087 +E_RC
48088 +IfIpAdd (IPV4_ADDR IfIpAddress, uns8 PrefixLen)
48090 + IF_IP_NODE *pIfIpNode;
48092 + if ((pIfIpNode =
48093 + (IF_IP_NODE *) XMALLOC (MTYPE_RSVP, sizeof (IF_IP_NODE))) == NULL)
48095 + zlog_err ("cannot allocate memory %s %d", __FILE__, __LINE__);
48096 + return E_ERR;
48098 + memset (pIfIpNode, 0, sizeof (IF_IP_NODE));
48099 + pIfIpNode->IfIpAddress = IfIpAddress;
48100 + pIfIpNode->PrefixLen = PrefixLen;
48101 + pIfIpNode->Node.key_info = (uns8 *) & pIfIpNode->IfIpAddress;
48102 + if (patricia_tree_add (&IfIpAddressesTree, &pIfIpNode->Node) != E_OK)
48104 + zlog_err ("cannot add node to patricia");
48105 + return E_ERR;
48107 + return E_OK;
48110 +E_RC
48111 +IfIpAddrDel (IPV4_ADDR IfIpAddress, uns8 PrefixLen)
48113 + IF_IP_NODE *pIfIpNode;
48115 + if ((pIfIpNode =
48116 + (IF_IP_NODE *) patricia_tree_get (&IfIpAddressesTree,
48117 + (const uns8 *) &IfIpAddress)) !=
48118 + NULL)
48120 + if (patricia_tree_del (&IfIpAddressesTree, &pIfIpNode->Node) != E_OK)
48122 + zlog_err ("Cannot delete from patricia %s %d", __FILE__, __LINE__);
48123 + return E_ERR;
48125 + return E_OK;
48127 + zlog_err ("IfIp entry is not found %s %d", __FILE__, __LINE__);
48128 + return E_ERR;
48131 +IPV4_ADDR
48132 +GetRouterId ()
48134 + IPV4_ADDR key = 0, SelectedIpAddr = 0;
48135 + IF_IP_NODE *pIfIpNode;
48137 + while ((pIfIpNode =
48138 + (IF_IP_NODE *) patricia_tree_getnext (&IfIpAddressesTree,
48139 + (const uns8 *) &key)) != NULL)
48141 + if (pIfIpNode->IfIpAddress > SelectedIpAddr)
48143 + SelectedIpAddr = pIfIpNode->IfIpAddress;
48145 + key = pIfIpNode->IfIpAddress;
48147 + return SelectedIpAddr;
48150 +uns8
48151 +IsAbstractNode (IPV4_ADDR IpAddress, uns8 PrefixLen)
48153 + IF_IP_NODE *pIfIpNode;
48154 + if (PrefixLen > 32)
48156 + zlog_warn ("PrefixLen is %d. Forcing to 32", PrefixLen);
48157 + PrefixLen = 32;
48159 + if ((pIfIpNode =
48160 + (IF_IP_NODE *) patricia_tree_get (&IfIpAddressesTree,
48161 + (const uns8 *) &IpAddress)) == NULL)
48163 + return FALSE;
48165 + return TRUE;
48168 +E_RC
48169 +InitInterfaceIpAdressesDB ()
48171 + PATRICIA_PARAMS params;
48173 + memset (&params, 0, sizeof (PATRICIA_PARAMS));
48174 + params.key_size = sizeof (IPV4_ADDR);
48175 + if (patricia_tree_init (&IfIpAddressesTree, &params) != E_OK)
48177 + zlog_err ("cannot initiate I/F patricia tree");
48178 + return E_ERR;
48180 + return E_OK;
48183 +E_RC
48184 +CheckRRO4Loop (RR_SUBOBJ * pRrSubObj)
48186 + RR_SUBOBJ *pRrSub = pRrSubObj;
48188 + while (pRrSub != NULL)
48190 + if (pRrSub->SubObjHdr.Type == RRO_SUBTYPE_IPV4)
48192 + if (IsAbstractNode (pRrSub->u.Ipv4.IpAddr, pRrSub->u.Ipv4.PrefixLen)
48193 + == TRUE)
48195 + return E_ERR;
48198 + pRrSub = pRrSub->next;
48200 + return E_OK;
48203 +void
48204 +FreeRRO (RR_OBJ * pRrObj)
48206 + RR_SUBOBJ *pRrSubObj, *pRrSubObjNext;
48208 + pRrSubObj = pRrObj->rr;
48209 + while (pRrSubObj != NULL)
48211 + pRrSubObjNext = pRrSubObj->next;
48212 + XFREE (MTYPE_RSVP, pRrSubObj);
48213 + pRrSubObj = pRrSubObjNext;
48215 + pRrObj->rr = NULL;
48218 +void
48219 +FreeERO (ER_OBJ * pErObj)
48221 + ER_SUBOBJ *pErSubObj, *pErSubObjNext;
48223 + pErSubObj = pErObj->er;
48224 + while (pErSubObj != NULL)
48226 + pErSubObjNext = pErSubObj->next;
48227 + XFREE (MTYPE_RSVP, pErSubObj);
48228 + pErSubObj = pErSubObjNext;
48230 + pErObj->er = NULL;
48233 +void
48234 +FreeSessionAttributes (SESSION_ATTRIBUTES_OBJ * pSessAttr)
48236 + if (pSessAttr->CType == SESSION_ATTRIBUTES_RA_IPV4_CTYPE)
48238 + if (pSessAttr->u.SessAttrRa.SessionName != NULL)
48240 + XFREE (MTYPE_RSVP, pSessAttr->u.SessAttrRa.SessionName);
48243 + else if (pSessAttr->CType == SESSION_ATTRIBUTES_IPV4_CTYPE)
48245 + if (pSessAttr->u.SessAttr.SessionName != NULL)
48247 + XFREE (MTYPE_RSVP, pSessAttr->u.SessAttr.SessionName);
48252 +void
48253 +FreeOpaqueObj (OPAQUE_OBJ_LIST * pOpaqueObjListHead)
48255 + OPAQUE_OBJ_LIST *pOpaqueObjList = pOpaqueObjListHead, *pOpaqueObjListNext;
48257 + while (pOpaqueObjList != NULL)
48259 + pOpaqueObjListNext = pOpaqueObjList->next;
48260 + if (pOpaqueObjList->pData)
48261 + XFREE (MTYPE_RSVP, pOpaqueObjList->pData);
48262 + XFREE (MTYPE_RSVP, pOpaqueObjList);
48263 + pOpaqueObjList = pOpaqueObjListNext;
48267 +void
48268 +FreeFilterSpecData (FILTER_SPEC_DATA ** ppFilterSpecData)
48270 + FILTER_SPEC_DATA *pFilterSpecData = *ppFilterSpecData;
48271 + zlog_info ("entering FreeFilterSpecData");
48272 + FreeRRO (&pFilterSpecData->Rro);
48273 + XFREE (MTYPE_RSVP, *ppFilterSpecData);
48274 + *ppFilterSpecData = NULL;
48275 + zlog_info ("leaving FreeFilterSpecData");
48278 +void
48279 +FreeRsvpPkt (RSVP_PKT * pRsvpPkt)
48281 + FILTER_LIST *pFilterList, *pFilterList2;
48282 + zlog_info ("entering FreeRsvpPkt");
48283 + FreeRRO (&pRsvpPkt->AddedRro);
48284 + FreeRRO (&pRsvpPkt->ReceivedRro);
48285 + FreeERO (&pRsvpPkt->ReceivedEro);
48286 + FreeERO (&pRsvpPkt->SentEro);
48287 + FreeSessionAttributes (&pRsvpPkt->SessionAttributes);
48288 + FreeOpaqueObj (pRsvpPkt->pIntegrityObj);
48289 + FreeOpaqueObj (pRsvpPkt->pPolicyDataObj);
48290 + FreeOpaqueObj (pRsvpPkt->pOpaqueObjList);
48291 + pFilterList = pRsvpPkt->pFilterList;
48292 + while (pFilterList != NULL)
48294 + FILTER_SPEC_DATA *pFilterSpecData = pFilterList->pFilterSpecData;
48295 + pFilterList2 = pFilterList->next;
48296 + if (DeleteFilterListNode (&pRsvpPkt->pFilterList,
48297 + pFilterSpecData) != E_OK)
48299 + zlog_err ("cannot delete filter list node %s %d", __FILE__,
48300 + __LINE__);
48302 + FreeFilterSpecData (&pFilterSpecData);
48303 + pFilterList = pFilterList2;
48305 + XFREE (MTYPE_RSVP, pRsvpPkt);
48306 + zlog_info ("leaving FreeRsvpPkt");
48309 +E_RC
48310 +EnqueueRsvpPacket (RSVP_PKT_QUEUE * pItem, RSVP_PKT_QUEUE ** ppQueueHead)
48312 + RSVP_PKT_QUEUE *pQueue;
48313 + zlog_info ("entering EnqueueRsvpPacket");
48315 + if ((*ppQueueHead) == NULL)
48317 + (*ppQueueHead) = pItem;
48318 + zlog_info ("leaving EnqueueRsvpPacket");
48319 + return E_OK;
48321 + pQueue = (*ppQueueHead);
48322 + while (pQueue->next != NULL)
48323 + pQueue = pQueue->next;
48324 + pQueue->next = pItem;
48325 + zlog_info ("leaving EnqueueRsvpPacket");
48326 + return E_OK;
48329 +RSVP_PKT_QUEUE *
48330 +DequeueRsvpPacket (RSVP_PKT_QUEUE ** ppQueueHead)
48332 + RSVP_PKT_QUEUE *pTemp;
48333 + zlog_info ("entering DequeueRsvpPacket");
48334 + if ((*ppQueueHead) == NULL)
48336 + return NULL;
48338 + pTemp = (*ppQueueHead);
48339 + (*ppQueueHead) = (*ppQueueHead)->next;
48340 + zlog_info ("leaving DequeueRsvpPacket");
48341 + return pTemp;
48344 +void
48345 +FreePSB (PSB * pPsb)
48347 + RSVP_PKT_QUEUE *pQueueItem;
48348 + zlog_info ("entering FreePSB");
48349 + if (pPsb->pSentBuffer)
48351 + XFREE (MTYPE_RSVP, pPsb->pSentBuffer);
48352 + pPsb->pSentBuffer = NULL;
48354 + if (RemovePsb (&pPsb->PsbKey) == E_OK)
48356 + if (pPsb->OldPacket.SessionAttributes.CType ==
48357 + SESSION_ATTRIBUTES_CLASS_TYPE)
48359 + if (pPsb->OldPacket.SessionAttributes.u.SessAttr.SessionName !=
48360 + NULL)
48362 + XFREE (MTYPE_RSVP,
48363 + pPsb->OldPacket.SessionAttributes.u.SessAttr.
48364 + SessionName);
48367 + else if (pPsb->OldPacket.SessionAttributes.CType ==
48368 + SESSION_ATTRIBUTES_RA_CLASS_TYPE)
48370 + if (pPsb->OldPacket.SessionAttributes.u.SessAttrRa.SessionName !=
48371 + NULL)
48373 + XFREE (MTYPE_RSVP,
48374 + pPsb->OldPacket.SessionAttributes.u.SessAttrRa.
48375 + SessionName);
48378 + FreeRRO (&pPsb->OldPacket.AddedRro);
48379 + FreeRRO (&pPsb->OldPacket.ReceivedRro);
48380 + FreeERO (&pPsb->OldPacket.ReceivedEro);
48381 + FreeERO (&pPsb->OldPacket.SentEro);
48382 + FreeOpaqueObj (pPsb->OldPacket.pIntegrityObj);
48383 + FreeOpaqueObj (pPsb->OldPacket.pPolicyDataObj);
48384 + FreeOpaqueObj (pPsb->OldPacket.pOpaqueObjList);
48385 + while ((pQueueItem = DequeueRsvpPacket (&pPsb->packet_queue)) != NULL)
48387 + FreeRsvpPkt (pQueueItem->pRsvpPkt);
48389 + XFREE (MTYPE_RSVP, pPsb);
48391 + else
48393 + zlog_err ("Freeing os PSB was not completed");
48395 + RsvpStatistics.DeletePsbCount++;
48396 + zlog_info ("leaving FreePSB");
48399 +void
48400 +FreeRSB (RSB * pRsb)
48402 + zlog_info ("entering FreeRSB");
48403 + if (RemoveRSB (&pRsb->RsbKey) == E_OK)
48405 + FreeOpaqueObj (pRsb->OldPacket.pIntegrityObj);
48406 + FreeOpaqueObj (pRsb->OldPacket.pPolicyDataObj);
48407 + FreeOpaqueObj (pRsb->OldPacket.pOpaqueObjList);
48408 + XFREE (MTYPE_RSVP, pRsb);
48410 + else
48412 + zlog_err ("Cannot free RSB");
48414 + RsvpStatistics.DeleteRsbCount++;
48415 + zlog_info ("leaving FreeRSB");
48418 +E_RC
48419 +InsertERO (ER_OBJ * pEro, ER_HOP * Path, uns16 HopNum)
48421 + int i;
48422 + ER_SUBOBJ *pErSubObjTail = pEro->er, *pErSubObjNew;
48424 + if (pErSubObjTail != NULL)
48426 + while (pErSubObjTail->next != NULL)
48428 + pErSubObjTail = pErSubObjTail->next;
48431 + for (i = 0; i < HopNum; i++)
48433 + pErSubObjNew = (ER_SUBOBJ *) XMALLOC (MTYPE_RSVP, sizeof (ER_SUBOBJ));
48434 + if (pErSubObjNew == NULL)
48436 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
48437 + return E_ERR;
48439 + if (pErSubObjTail == NULL)
48441 + pEro->er = pErSubObjNew;
48442 + pErSubObjTail = pErSubObjNew;
48444 + else
48446 + pErSubObjTail->next = pErSubObjNew;
48447 + pErSubObjTail = pErSubObjTail->next;
48449 + memset (pErSubObjTail, 0, sizeof (ER_SUBOBJ));
48450 + pErSubObjTail->SubObjHdr.LType = ERO_SUBTYPE_IPV4;
48451 + pErSubObjTail->SubObjHdr.Length = 8;
48452 + pErSubObjTail->u.Ipv4.IpAddress = Path[i].IpAddr;
48453 + pErSubObjTail->u.Ipv4.PrefixLength = Path[i].PrefixLength;
48454 + if (Path[i].Loose)
48455 + pErSubObjTail->SubObjHdr.LType |= 0x80;
48457 + return E_OK;
48460 +E_RC
48461 +InsertRRO (RSVP_PKT * pRsvpPkt)
48463 + RR_SUBOBJ *pRrSub = pRsvpPkt->AddedRro.rr, *pRrSubNew;
48465 + pRrSubNew = XMALLOC (MTYPE_RSVP, sizeof (RR_SUBOBJ));
48466 + if (!pRrSubNew)
48468 + return E_ERR;
48470 + pRrSubNew->SubObjHdr.Length = 8;
48471 + pRrSubNew->SubObjHdr.Type = RRO_SUBTYPE_IPV4;
48472 + pRrSubNew->u.Ipv4.Flags = 0;
48473 + pRrSubNew->u.Ipv4.IpAddr = GetRouterId ();
48474 + pRrSubNew->u.Ipv4.PrefixLen = 32;
48475 + if (pRrSub)
48477 + pRrSub = pRsvpPkt->AddedRro.rr;
48478 + while (pRrSub->next != NULL)
48480 + pRrSub = pRrSub->next;
48482 + pRrSub->next = pRrSubNew;
48484 + else
48486 + pRsvpPkt->AddedRro.rr = pRrSubNew;
48488 + return E_OK;
48491 +void
48492 +DumpSession (RSVP_PKT * pRsvpPkt, struct vty *vty)
48494 + LOG4 ("SESSION: Dest %x Tunnel %x ExtTunnel %x",
48495 + pRsvpPkt->Session.Dest,
48496 + pRsvpPkt->Session.TunnelId, pRsvpPkt->Session.ExtTunelId);
48499 +void
48500 +DumpSenderTemplate (RSVP_PKT * pRsvpPkt, struct vty *vty)
48502 + LOG3 ("SENDER_TEMPLATE: SrcIp %x LSP %x",
48503 + pRsvpPkt->SenderTemplate.IpAddr, pRsvpPkt->SenderTemplate.LspId);
48506 +void
48507 +DumpSenderTSPec (RSVP_PKT * pRsvpPkt, struct vty *vty)
48509 + LOG6
48510 + ("SENDER_TSPEC: TockenBucketRate %f TockenBucketSize %f PeakDataRate %f MinPolicedUnit %x MaxPacketSize %x",
48511 + pRsvpPkt->SenderTSpec.TockenBucketRate,
48512 + pRsvpPkt->SenderTSpec.TockenBucketSize,
48513 + pRsvpPkt->SenderTSpec.PeakDataRate, pRsvpPkt->SenderTSpec.MinPolicedUnit,
48514 + pRsvpPkt->SenderTSpec.MaxPacketSize);
48517 +void
48518 +DumpRsvpHop (RSVP_PKT * pRsvpPkt, struct vty *vty)
48520 + RSVP_HOP_OBJ RsvpHop;
48521 + memset (&RsvpHop, 0, sizeof (RSVP_HOP_OBJ));
48522 + if (memcmp (&pRsvpPkt->SentRsvpHop, &RsvpHop, sizeof (RSVP_HOP_OBJ)) != 0)
48524 + LOG3 ("RSVP_HOP: IP %x LIH %x",
48525 + pRsvpPkt->SentRsvpHop.PHop, pRsvpPkt->SentRsvpHop.LIH);
48527 + else
48529 + LOG3 ("RSVP_HOP: IP %x LIH %x",
48530 + pRsvpPkt->ReceivedRsvpHop.PHop, pRsvpPkt->ReceivedRsvpHop.LIH);
48534 +void
48535 +DumpSessionAttr (RSVP_PKT * pRsvpPkt, struct vty *vty)
48537 + if (pRsvpPkt->SessionAttributes.CType == SESSION_ATTRIBUTES_RA_IPV4_CTYPE)
48539 + LOG1 ("SESSION_ATTRIBUTES with RA");
48540 + LOG4 ("%x %x %x",
48541 + pRsvpPkt->SessionAttributes.u.SessAttrRa.ExcludeAny,
48542 + pRsvpPkt->SessionAttributes.u.SessAttrRa.IncludeAny,
48543 + pRsvpPkt->SessionAttributes.u.SessAttrRa.IncludeAll);
48544 + LOG4 ("Flags: %x HoldPrio %x SetPrio %x",
48545 + pRsvpPkt->SessionAttributes.u.SessAttrRa.Flags,
48546 + pRsvpPkt->SessionAttributes.u.SessAttrRa.HoldPrio,
48547 + pRsvpPkt->SessionAttributes.u.SessAttrRa.SetPrio);
48548 + if ((pRsvpPkt->SessionAttributes.u.SessAttrRa.NameLength != 0) &&
48549 + (pRsvpPkt->SessionAttributes.u.SessAttrRa.SessionName != NULL))
48551 + LOG2 ("SessionName %s",
48552 + pRsvpPkt->SessionAttributes.u.SessAttrRa.SessionName);
48555 + else if (pRsvpPkt->SessionAttributes.CType == SESSION_ATTRIBUTES_IPV4_CTYPE)
48557 + LOG1 ("SESSION_ATTRIBUTES w/o RA");
48558 + LOG4 ("Flags: %x HoldPrio %x SetPrio %x",
48559 + pRsvpPkt->SessionAttributes.u.SessAttr.Flags,
48560 + pRsvpPkt->SessionAttributes.u.SessAttr.HoldPrio,
48561 + pRsvpPkt->SessionAttributes.u.SessAttr.SetPrio);
48562 + if ((pRsvpPkt->SessionAttributes.u.SessAttr.NameLength != 0) &&
48563 + (pRsvpPkt->SessionAttributes.u.SessAttr.SessionName != NULL))
48565 + LOG2 ("SessionName %s",
48566 + pRsvpPkt->SessionAttributes.u.SessAttr.SessionName);
48571 +void
48572 +DumpTimeValues (RSVP_PKT * pRsvpPkt, struct vty *vty)
48574 + LOG2 ("TIME_VALUES %x", pRsvpPkt->TimeValues.TimeValues);
48577 +void
48578 +DumpAdSpec (RSVP_PKT * pRsvpPkt, struct vty *vty)
48580 + LOG1 ("ADSPEC");
48581 + if (pRsvpPkt->SentAdSpec.CType != 0)
48583 + LOG5 ("ComposedMTU %x IS_HopCount %x MinPathLatency %x PathBW %f",
48584 + pRsvpPkt->SentAdSpec.AdSpecGen.ComposedMTU,
48585 + pRsvpPkt->SentAdSpec.AdSpecGen.IS_HopCount,
48586 + pRsvpPkt->SentAdSpec.AdSpecGen.MinPathLatency,
48587 + pRsvpPkt->SentAdSpec.AdSpecGen.PathBW);
48589 + else if (pRsvpPkt->ReceivedAdSpec.CType != 0)
48591 + LOG5 ("ComposedMTU %x IS_HopCount %x MinPathLatency %x PathBW %f",
48592 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.ComposedMTU,
48593 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.IS_HopCount,
48594 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.MinPathLatency,
48595 + pRsvpPkt->ReceivedAdSpec.AdSpecGen.PathBW);
48599 +void
48600 +DumpRRO (RR_SUBOBJ * pRrSubObj, struct vty *vty)
48602 + LOG1 ("RRO");
48603 + while (pRrSubObj != NULL)
48605 + switch (pRrSubObj->SubObjHdr.Type)
48607 + case RRO_SUBTYPE_IPV4:
48608 + LOG4 ("IP %x PrefixLen %x Flags %x",
48609 + pRrSubObj->u.Ipv4.IpAddr,
48610 + pRrSubObj->u.Ipv4.PrefixLen, pRrSubObj->u.Ipv4.Flags);
48611 + break;
48612 + case RRO_SUBTYPE_LABEL:
48613 + LOG3 ("LABEL %x Flags %x",
48614 + pRrSubObj->u.Label.Label, pRrSubObj->u.Label.Flags);
48615 + break;
48616 + default:
48617 + LOG2 ("RR subobject of unknown type %x", pRrSubObj->SubObjHdr.Type);
48619 + pRrSubObj = pRrSubObj->next;
48623 +void
48624 +DumpERO (ER_SUBOBJ * pErSubObj, struct vty *vty)
48626 + LOG1 ("ERO");
48627 + while (pErSubObj != NULL)
48629 + if (pErSubObj->SubObjHdr.LType & 0x80)
48631 + LOG1 ("LOOSE");
48633 + switch (pErSubObj->SubObjHdr.LType & 0x7F)
48635 + case ERO_SUBTYPE_IPV4:
48636 + LOG3 ("IP %x PrefixLen %x", pErSubObj->u.Ipv4.IpAddress,
48637 + pErSubObj->u.Ipv4.PrefixLength);
48638 + break;
48639 + case ERO_SUBTYPE_AS:
48640 + LOG2 ("AS %x", pErSubObj->u.AS.AsNumber);
48641 + break;
48642 + default:
48643 + LOG2 ("ER subobject of unknown type %x",
48644 + (pErSubObj->SubObjHdr.LType & 0x7F));
48646 + pErSubObj = pErSubObj->next;
48650 +void
48651 +DumpPathMsg (RSVP_PKT * pRsvpPkt, struct vty *vty)
48653 + DumpSession (pRsvpPkt, vty);
48654 + DumpSenderTemplate (pRsvpPkt, vty);
48655 + DumpSenderTSPec (pRsvpPkt, vty);
48656 + DumpRsvpHop (pRsvpPkt, vty);
48657 + DumpSessionAttr (pRsvpPkt, vty);
48658 + DumpTimeValues (pRsvpPkt, vty);
48659 + DumpAdSpec (pRsvpPkt, vty);
48660 + DumpERO (pRsvpPkt->ReceivedEro.er, vty);
48661 + DumpERO (pRsvpPkt->SentEro.er, vty);
48662 + DumpRRO (pRsvpPkt->ReceivedRro.rr, vty);
48663 + DumpRRO (pRsvpPkt->AddedRro.rr, vty);
48666 +void
48667 +DumpFilterSpec (FILTER_SPEC_OBJ * pFilterSpec, struct vty *vty)
48669 + LOG3 ("IP %x LSP %x", pFilterSpec->IpAddr, pFilterSpec->LspId);
48672 +void
48673 +DumpFlowSpec (FLOW_SPEC_OBJ * pFlowSpec, struct vty *vty)
48675 + if (pFlowSpec->ServHdr.ServHdr == FLOW_SPEC_CTRL_LOAD_SERV_NUMBER)
48677 + LOG6
48678 + ("TockenBucketRate %f TockenBucketSize %f PeakDataRate %f MinPolicedUnit %f MaxPacketSize %f",
48679 + pFlowSpec->u.CtrlLoad.TockenBucketRate,
48680 + pFlowSpec->u.CtrlLoad.TockenBucketSize,
48681 + pFlowSpec->u.CtrlLoad.PeakDataRate,
48682 + pFlowSpec->u.CtrlLoad.MinPolicedUnit,
48683 + pFlowSpec->u.CtrlLoad.MaxPacketSize);
48685 + else if (pFlowSpec->ServHdr.ServHdr == FLOW_SPEC_GUAR_SERV_NUMBER)
48687 + LOG6
48688 + ("TockenBucketRate %f TockenBucketSize %f PeakDataRate %f MinPolicedUnit %f MaxPacketSize %f",
48689 + pFlowSpec->u.Guar.CtrlLoad.TockenBucketRate,
48690 + pFlowSpec->u.Guar.CtrlLoad.TockenBucketSize,
48691 + pFlowSpec->u.Guar.CtrlLoad.PeakDataRate,
48692 + pFlowSpec->u.Guar.CtrlLoad.MinPolicedUnit,
48693 + pFlowSpec->u.Guar.CtrlLoad.MaxPacketSize);
48694 + LOG3 ("Rate %f SlackTerm %x", pFlowSpec->u.Guar.Rate,
48695 + pFlowSpec->u.Guar.SlackTerm);
48699 +void
48700 +DumpFlowDescr (RSVP_PKT * pRsvpPkt, struct vty *vty)
48702 + FILTER_LIST *pFilterList = pRsvpPkt->pFilterList;
48703 + while (pFilterList != NULL)
48705 + FILTER_SPEC_DATA *pFilterSpecData;
48706 + if ((pFilterSpecData = pFilterList->pFilterSpecData) == NULL)
48708 + pFilterList = pFilterList->next;
48709 + continue;
48711 + DumpFilterSpec (&pFilterSpecData->FilterSpec, vty);
48712 + DumpFlowSpec (&pFilterSpecData->FlowSpec, vty);
48713 + LOG2 ("Label %x", pFilterSpecData->ReceivedLabel.Label);
48714 + DumpRRO (pFilterSpecData->Rro.rr, vty);
48715 + pFilterList = pFilterList->next;
48719 +void
48720 +DumpStyle (RSVP_PKT * pRsvpPkt, struct vty *vty)
48722 + LOG2 ("STYLE %x", pRsvpPkt->Style.OptionVector2);
48725 +void
48726 +DumpResvMsg (RSVP_PKT * pRsvpPkt, struct vty *vty)
48728 + DumpSession (pRsvpPkt, vty);
48729 + DumpTimeValues (pRsvpPkt, vty);
48730 + DumpRsvpHop (pRsvpPkt, vty);
48731 + DumpStyle (pRsvpPkt, vty);
48732 + DumpFlowDescr (pRsvpPkt, vty);
48735 +void
48736 +DumpErrSpec (RSVP_PKT * pRsvpPkt, struct vty *vty)
48738 + LOG5 ("Error code %x Error value %x IP %x flags %x",
48739 + pRsvpPkt->ErrorSpec.ErrCode,
48740 + pRsvpPkt->ErrorSpec.ErrVal,
48741 + pRsvpPkt->ErrorSpec.IpAddr, pRsvpPkt->ErrorSpec.Flags);
48744 +void
48745 +DumpPathErrMsg (RSVP_PKT * pRsvpPkt, struct vty *vty)
48747 + DumpSession (pRsvpPkt, vty);
48748 + DumpErrSpec (pRsvpPkt, vty);
48749 + DumpSenderTemplate (pRsvpPkt, vty);
48750 + DumpSenderTSPec (pRsvpPkt, vty);
48753 +void
48754 +DumpResvErrMsg (RSVP_PKT * pRsvpPkt, struct vty *vty)
48756 + DumpSession (pRsvpPkt, vty);
48757 + DumpRsvpHop (pRsvpPkt, vty);
48758 + DumpErrSpec (pRsvpPkt, vty);
48759 + DumpStyle (pRsvpPkt, vty);
48760 + DumpFlowDescr (pRsvpPkt, vty);
48763 +void
48764 +DumpPathTearMsg (RSVP_PKT * pRsvpPkt, struct vty *vty)
48766 + DumpSession (pRsvpPkt, vty);
48767 + DumpRsvpHop (pRsvpPkt, vty);
48768 + DumpSenderTemplate (pRsvpPkt, vty);
48769 + DumpSenderTSPec (pRsvpPkt, vty);
48772 +void
48773 +DumpResvTearMsg (RSVP_PKT * pRsvpPkt, struct vty *vty)
48775 + DumpSession (pRsvpPkt, vty);
48776 + DumpRsvpHop (pRsvpPkt, vty);
48777 + DumpStyle (pRsvpPkt, vty);
48778 + DumpFlowDescr (pRsvpPkt, vty);
48781 +void
48782 +DumpPSB (PSB_KEY * pPsbKey, struct vty *vty)
48784 + PSB_KEY PsbKey;
48785 + PSB *pPsb;
48787 + memset (&PsbKey, 0, sizeof (PSB_KEY));
48789 + if (memcmp (pPsbKey, &PsbKey, sizeof (PSB_KEY)) == 0)
48791 + while ((pPsb = GetNextPSB (&PsbKey)) != NULL)
48793 + LOG8
48794 + ("InIfIndex %x Label %x NextHop %x OutIfIndex %x TTL %x PrevHop %x TE_InProcess %x",
48795 + pPsb->InIfIndex, pPsb->Label, pPsb->NextHop, pPsb->OutIfIndex,
48796 + pPsb->ttl, pPsb->PrevHop, pPsb->TE_InProcess);
48797 + LOG5
48798 + ("AgeOutValue %x AgeOutTimer %s RefreshValue %x RefreshTimer %s",
48799 + pPsb->AgeOutValue,
48800 + (pPsb->AgeOutTimer == (uns32) NULL) ? "stopped" : "running",
48801 + pPsb->RefreshValue,
48802 + (pPsb->PathRefreshTimer ==
48803 + (uns32) NULL) ? "stopped" : "running");
48804 + LOG3 ("%s %s",
48805 + (pPsb->pSentBuffer ==
48806 + NULL) ? "hasn't already encoded buffer (for refresh)" :
48807 + "has encoded buffer for refresh",
48808 + (pPsb->pRsb == NULL) ? "hasn't RSB" : "has RSB");
48809 + DumpPathMsg (&pPsb->OldPacket, vty);
48810 + PsbKey = pPsb->PsbKey;
48813 + else
48815 + if ((pPsb = FindPsb (pPsbKey)) != NULL)
48817 + LOG8
48818 + ("InIfIndex %x Label %x NextHop %x OutIfIndex %x TTL %x PrevHop %x TE_InProcess %x",
48819 + pPsb->InIfIndex, pPsb->Label, pPsb->NextHop, pPsb->OutIfIndex,
48820 + pPsb->ttl, pPsb->PrevHop, pPsb->TE_InProcess);
48821 + LOG5
48822 + ("AgeOutValue %x AgeOutTimer %s RefreshValue %x RefreshTimer %s",
48823 + pPsb->AgeOutValue,
48824 + (pPsb->AgeOutTimer == (uns32) NULL) ? "stopped" : "running",
48825 + pPsb->RefreshValue,
48826 + (pPsb->PathRefreshTimer ==
48827 + (uns32) NULL) ? "stopped" : "running");
48828 + LOG3 ("%s %s",
48829 + (pPsb->pSentBuffer ==
48830 + NULL) ? "has already encoded buffer (for refresh)" :
48831 + "hasn't encoded buffer for refresh",
48832 + (pPsb->pRsb == NULL) ? "hasn't RSB" : "has RSB");
48833 + DumpPathMsg (&pPsb->OldPacket, vty);
48839 +void
48840 +DumpSingleRSB (RSB * pRsb, struct vty *vty)
48842 + FILTER_LIST *pFilterList = pRsb->OldPacket.pFilterList;
48844 + while (pFilterList != NULL)
48846 + FILTER_SPEC_DATA *pFilterSpecData = pFilterList->pFilterSpecData;
48847 + if (pFilterSpecData == NULL)
48849 + pFilterList = pFilterList->next;
48850 + continue;
48852 + DumpFilterSpec (&pFilterSpecData->FilterSpec, vty);
48853 + if (pFilterSpecData->NewFlowSpecValid)
48855 + DumpFlowSpec (&pFilterSpecData->NewFlowSpec, vty);
48857 + DumpFlowSpec (&pFilterSpecData->FlowSpec, vty);
48858 + LOG2 ("Label %x", pFilterSpecData->ReceivedLabel.Label);
48859 + DumpRRO (pFilterSpecData->Rro.rr, vty);
48860 + if (pFilterSpecData->pEffectiveFlow != NULL)
48862 + LOG3 ("IfIndex %x %s",
48863 + pFilterSpecData->pEffectiveFlow->IfIndex,
48864 + (pFilterSpecData->pEffectiveFlow->MustBeProcessed ==
48865 + 1) ? "MustBeProcessed" : "");
48866 + DumpFlowSpec (&pFilterSpecData->pEffectiveFlow->CurrentFlowSpec,
48867 + vty);
48868 + DumpFlowSpec (&pFilterSpecData->pEffectiveFlow->NewFlowSpec, vty);
48870 + if (pFilterSpecData->pPHopResvRefreshList != NULL)
48872 + LOG8
48873 + ("PHOP IP %x PHOP LIH %x InIfIndex %x %s RefreshValue %x %s %s",
48874 + pFilterSpecData->pPHopResvRefreshList->PHop.PHop,
48875 + pFilterSpecData->pPHopResvRefreshList->PHop.LIH,
48876 + pFilterSpecData->pPHopResvRefreshList->InIfIndex,
48877 + (pFilterSpecData->pPHopResvRefreshList->MustBeProcessed ==
48878 + 1) ? "MustBeProcessed" : "",
48879 + pFilterSpecData->pPHopResvRefreshList->RefreshValue,
48880 + (pFilterSpecData->pPHopResvRefreshList->ResvRefreshTimer ==
48881 + (uns32) NULL) ? "refresh timer is stopped" :
48882 + "refresh timer is running",
48883 + (pFilterSpecData->pPHopResvRefreshList->pSentBuffer ==
48884 + NULL) ? "hasn't encoded buffer for refresh" :
48885 + "has encoded buffer for refresh");
48886 + DumpRRO (pFilterSpecData->pPHopResvRefreshList->pAddedRro, vty);
48887 + DumpFlowSpec (&pFilterSpecData->pPHopResvRefreshList->FwdFlowSpec,
48888 + vty);
48890 + LOG3 ("AgeOut value %x %s",
48891 + pFilterSpecData->AgeOutValue,
48892 + (pFilterSpecData->AgeOutTimer ==
48893 + (uns32) NULL) ? "age out timer is not running" :
48894 + "age out timer is running");
48895 + pFilterList = pFilterList->next;
48899 +void
48900 +DumpRSB (RSB_KEY * pRsbKey, struct vty *vty)
48902 + RSB_KEY RsbKey;
48903 + RSB *pRsb;
48905 + memset (&RsbKey, 0, sizeof (RSB_KEY));
48907 + if (memcmp (&RsbKey, pRsbKey, sizeof (RSB_KEY)) == 0)
48909 + while ((pRsb = GetNextRSB (&RsbKey)) != NULL)
48911 + DumpSingleRSB (pRsb, vty);
48912 + RsbKey = pRsb->RsbKey;
48915 + else
48917 + if ((pRsb = FindRsb (pRsbKey)) != NULL)
48919 + DumpSingleRSB (pRsb, vty);
48924 +void
48925 +DumpRsvpStatistics (struct vty *vty)
48927 + LOG7
48928 + ("PathMsg %d ResvMsg %d PathTearMsg %d ResvTearMsg %d PathErrMsg %d ResvErrMsg %d",
48929 + RsvpStatistics.PathMsgCount, RsvpStatistics.ResvMsgCount,
48930 + RsvpStatistics.PathTearMsgCount, RsvpStatistics.ResvTearMsgCount,
48931 + RsvpStatistics.PathErrMsgCount, RsvpStatistics.ResvErrMsgCount);
48932 + LOG6 ("NewPsb %d DeletedPsb %d NewRsb %d DeletedRsb %d NewFilters %d",
48933 + RsvpStatistics.NewPsbCount, RsvpStatistics.DeletePsbCount,
48934 + RsvpStatistics.NewRsbCount, RsvpStatistics.DeleteRsbCount,
48935 + RsvpStatistics.NewFiltersCount);
48936 + LOG3 ("PathAgeOut %d FilterAgeOut %d", RsvpStatistics.PsbAgeOutCount,
48937 + RsvpStatistics.FilterAgeOutCount);
48940 +int
48941 +RefreshRandomize (uns32 RefreshTimeBase)
48943 + uns32 Range = RefreshTimeBase / 10;
48944 + int k = rand ();
48945 + while (k > Range)
48946 + k = k / 3;
48947 + return (k % 2) ? k : -k;
48949 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_utilities.h quagga-mpls/rsvpd/rsvp_utilities.h
48950 --- quagga/rsvpd/rsvp_utilities.h 1969-12-31 18:00:00.000000000 -0600
48951 +++ quagga-mpls/rsvpd/rsvp_utilities.h 2007-06-14 21:35:58.000000000 -0500
48952 @@ -0,0 +1,59 @@
48954 +#ifndef _RSVP_UTILITIES_H_
48955 +#define _RSVP_UTILITIES_H_
48957 +typedef struct _rsvp_statistics_
48959 + uns32 NewPsbCount;
48960 + uns32 DeletePsbCount;
48961 + uns32 NewRsbCount;
48962 + uns32 DeleteRsbCount;
48963 + uns32 NewFiltersCount;
48964 + uns32 PsbAgeOutCount;
48965 + uns32 FilterAgeOutCount;
48966 + uns32 PathMsgCount;
48967 + uns32 ResvMsgCount;
48968 + uns32 PathTearMsgCount;
48969 + uns32 ResvTearMsgCount;
48970 + uns32 PathErrMsgCount;
48971 + uns32 ResvErrMsgCount;
48972 +} RSVP_STATISTICS;
48975 +E_RC EnqueueRsvpPacket (RSVP_PKT_QUEUE * pItem,
48976 + RSVP_PKT_QUEUE ** ppQueueHead);
48977 +RSVP_PKT_QUEUE *DequeueRsvpPacket (RSVP_PKT_QUEUE ** ppQueueHead);
48979 +int RefreshRandomize (uns32 RefreshTimeBase);
48981 +E_RC InsertRRO (RSVP_PKT * pRsvpPkt);
48983 +E_RC InsertERO (ER_OBJ * pEro, ER_HOP * Path, uns16 HopNum);
48985 +void FreeRSB (RSB * pRsb);
48987 +void FreePSB (PSB * pPsb);
48989 +void FreeRsvpPkt (RSVP_PKT * pRsvpPkt);
48991 +void FreeERO (ER_OBJ *);
48992 +void FreeRRO (RR_OBJ *);
48993 +void FreeFilterSpecData (FILTER_SPEC_DATA ** ppFilterSpecData);
48995 +E_RC IfIpAdd (IPV4_ADDR IfIpAddress, uns8 PrefixLen);
48996 +E_RC IfIpAddrDel (IPV4_ADDR IfIpAddress, uns8 PrefixLen);
48998 +void DumpResvTearMsg (RSVP_PKT * pRsvpPkt, struct vty *vty);
48999 +void DumpResvMsg (RSVP_PKT * pRsvpPkt, struct vty *vty);
49000 +void DumpPathErrMsg (RSVP_PKT * pRsvpPkt, struct vty *vty);
49001 +void DumpResvErrMsg (RSVP_PKT * pRsvpPkt, struct vty *vty);
49002 +void DumpPathMsg (RSVP_PKT * pRsvpPkt, struct vty *vty);
49003 +void DumpPathTearMsg (RSVP_PKT * pRsvpPkt, struct vty *vty);
49004 +IPV4_ADDR GetRouterId ();
49005 +E_RC CheckRRO4Loop (RR_SUBOBJ * pRrSubObj);
49006 +uns8 IsAbstractNode (IPV4_ADDR IpAddress, uns8 PrefixLen);
49007 +E_RC InitInterfaceIpAdressesDB ();
49008 +void DumpRSB (RSB_KEY * pRsbKey, struct vty *vty);
49009 +void DumpPSB (PSB_KEY * pPsbKey, struct vty *vty);
49010 +void DumpRsvpStatistics (struct vty *vty);
49011 +#endif
49012 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_vty.c quagga-mpls/rsvpd/rsvp_vty.c
49013 --- quagga/rsvpd/rsvp_vty.c 1969-12-31 18:00:00.000000000 -0600
49014 +++ quagga-mpls/rsvpd/rsvp_vty.c 2007-07-02 23:41:07.000000000 -0500
49015 @@ -0,0 +1,656 @@
49016 +/* Module: rsvp_vty.c
49017 + Contains: RSVP vty function
49018 + Module creator: original code by Vadim Suraev, vadim_suraev@hotmail.com
49019 + adapted by James R. Leu, jleu@mindspring.com
49020 + */
49022 +#include <zebra.h>
49024 +#include "memory.h"
49025 +#include "thread.h"
49026 +#include "vty.h"
49027 +#include "command.h"
49028 +#include "log.h"
49030 +#include "rsvp.h"
49031 +#include "te.h"
49032 +#include "te_cspf.h"
49034 +char MplsTePrompt[50] = "%s(mpls_te_tunnel-";
49035 +char CurrentTunnelName[20];
49037 +struct cmd_node mpls_te_conf_node = {
49038 + MPLS_TE_TUNNEL_CONF_NODE,
49039 + ""
49042 +struct cmd_node mpls_te_tunnel_node = {
49043 + MPLS_TE_TUNNEL_NODE,
49044 + MplsTePrompt,
49048 +int
49049 +DummyConfigWrite (struct vty *vty)
49051 + return 0;
49054 +void
49055 +WriteTunnel (USER_LSP * pUserLsp, struct vty *vty)
49057 + struct in_addr tmp;
49058 + tmp.s_addr = ntohl (pUserLsp->params.to);
49059 + vty_out (vty, "interface tunnel %s%s", pUserLsp->params.LspName,
49060 + VTY_NEWLINE);
49061 + vty_out (vty, " tunnel destination %s%s", inet_ntoa (tmp), VTY_NEWLINE);
49062 + if (pUserLsp->params.lsp_params.BW)
49064 +#if 0 /* for now - no support for floating point input */
49065 + vty_out (vty, " tunnel mpls traffic-eng bandwidth %f%s",
49066 + pUserLsp->params.lsp_params.BW, VTY_NEWLINE);
49067 +#else
49068 + int bw = pUserLsp->params.lsp_params.BW;
49069 + vty_out (vty, " tunnel mpls traffic-eng bandwidth %d%s",
49070 + /*pUserLsp->params.lsp_params.BW */ bw,
49071 + VTY_NEWLINE);
49072 +#endif
49075 + if ((pUserLsp->params.lsp_params.setup_priority != 4) ||
49076 + (pUserLsp->params.lsp_params.hold_priority != 4))
49078 + vty_out (vty, " tunnel mpls traffic-eng priority %d %d%s",
49079 + pUserLsp->params.lsp_params.setup_priority,
49080 + pUserLsp->params.lsp_params.hold_priority, VTY_NEWLINE);
49082 + if (pUserLsp->params.lsp_params.hop_limit)
49084 + vty_out (vty, " tunnel mpls traffic-eng hop-limit %d%s",
49085 + pUserLsp->params.lsp_params.hop_limit, VTY_NEWLINE);
49087 + if (pUserLsp->params.lsp_params.optimize_timer)
49089 + vty_out (vty, " tunnel mpls traffic-eng optimize-timer %d%s",
49090 + pUserLsp->params.lsp_params.optimize_timer, VTY_NEWLINE);
49092 + if (pUserLsp->params.lsp_params.record)
49094 + vty_out (vty, " tunnel mpls traffic-eng record-route%s", VTY_NEWLINE);
49096 + if (pUserLsp->params.lsp_params.affinity_properties)
49098 + vty_out (vty, " tunnel mpls traffic-eng affinity %x %x%s",
49099 + pUserLsp->params.lsp_params.affinity_properties,
49100 + pUserLsp->params.lsp_params.affinity_mask, VTY_NEWLINE);
49102 + if (pUserLsp->params.retry_timer)
49104 + vty_out (vty, " tunnel mpls traffic-eng retry-timer %d%s",
49105 + pUserLsp->params.retry_timer, VTY_NEWLINE);
49107 + if (pUserLsp->params.retry_limit)
49109 + vty_out (vty, " tunnel mpls traffic-eng retry-limit %d%s",
49110 + pUserLsp->params.retry_limit, VTY_NEWLINE);
49112 + vty_out (vty, " exit%s", VTY_NEWLINE);
49115 +int
49116 +MPLS_TE_ConfigWrite (struct vty *vty)
49118 + UserLspLoop ((LSP_LOOP_CALLBACK_T) WriteTunnel, vty);
49119 + return 0;
49122 +static void
49123 +TeEndConfigureCallback (struct vty *vty)
49125 + USER_LSP *pUserLsp;
49126 + SM_CALL_T *pCall;
49128 + pUserLsp = vty->index;
49130 + if ((pCall =
49131 + lsp_sm_sync_invoke (0, pUserLsp, USER_LSP_REQUEST_EVENT)) == NULL)
49133 + zlog_err ("\ncan not invoke sm %s %d", __FILE__, __LINE__);
49135 + else
49137 + zlog_info ("%s %d", __FILE__, __LINE__);
49138 + sm_call (pCall);
49142 +DEFUN (mpls_te_tunnel,
49143 + mpls_te_tunnel_cmd,
49144 + "interface tunnel WORD ",
49145 + "MPLS TE tunnel name\n" "Start MPLS TE tunnel configuration\n")
49147 + USER_LSP *pUserLsp, *pCurrUserLsp;
49148 + vty->node = MPLS_TE_TUNNEL_NODE;
49149 + strcpy (CurrentTunnelName, argv[0]);
49150 + strcpy (MplsTePrompt, "%s(mpls_te_tunnel-");
49151 + strcat (MplsTePrompt, CurrentTunnelName);
49152 + strcat (MplsTePrompt, ")# ");
49153 + if ((pUserLsp = (USER_LSP *) XMALLOC (MTYPE_TE, sizeof (USER_LSP))) == NULL)
49155 + zlog_info ("leaving UserLspAPI %s %d", __FILE__, __LINE__);
49156 + return CMD_SUCCESS;
49158 + memset (pUserLsp, 0, sizeof (USER_LSP));
49159 + strcpy (pUserLsp->params.LspName, CurrentTunnelName);
49160 + if ((pCurrUserLsp = UserLspGet (pUserLsp->params.LspName)) != NULL)
49162 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params, *pSrcParams =
49163 + &pCurrUserLsp->params;
49164 + SECONDARY_PATH_LIST *pSrcSecPathList =
49165 + pSrcParams->SecondaryPaths, *pDestSecPathList = NULL, *pPathListTemp;
49166 + pDestParams->to = pSrcParams->to;
49167 + pDestParams->from = pSrcParams->from;
49168 + pDestParams->metric = pSrcParams->metric;
49169 + pDestParams->no_decrement_ttl = pSrcParams->no_decrement_ttl;
49170 + pDestParams->bw_policy = pSrcParams->bw_policy;
49171 + pDestParams->retry_timer = pSrcParams->retry_timer;
49172 + pDestParams->retry_limit = pSrcParams->retry_limit;
49173 + pDestParams->FastReRoute = pSrcParams->FastReRoute;
49174 + strcpy (pDestParams->PolicyName, pSrcParams->PolicyName);
49175 + memcpy (&pDestParams->lsp_params, &pSrcParams->lsp_params,
49176 + sizeof (LSP_PATH_SHARED_PARAMS));
49177 + strcpy (pDestParams->Primary, pSrcParams->Primary);
49178 + if (pSrcParams->PrimaryPathParams != NULL)
49180 + if ((pDestParams->PrimaryPathParams =
49181 + (LSP_PATH_SHARED_PARAMS *) XMALLOC (MTYPE_TE,
49182 + sizeof
49183 + (LSP_PATH_SHARED_PARAMS)))
49184 + == NULL)
49186 + zlog_info ("leaving UserLspAPI %s %d", __FILE__, __LINE__);
49187 + return CMD_SUCCESS;
49189 + memcpy (pDestParams->PrimaryPathParams,
49190 + pSrcParams->PrimaryPathParams,
49191 + sizeof (LSP_PATH_SHARED_PARAMS));
49193 + while (pSrcSecPathList != NULL)
49195 + if ((pPathListTemp =
49196 + (SECONDARY_PATH_LIST *) XMALLOC (MTYPE_TE,
49197 + sizeof (SECONDARY_PATH_LIST)))
49198 + == NULL)
49200 + zlog_info ("leaving UserLspAPI %s %d", __FILE__, __LINE__);
49201 + return CMD_SUCCESS;
49203 + memset (pPathListTemp, 0, sizeof (SECONDARY_PATH_LIST));
49204 + if (pDestParams->SecondaryPaths == NULL)
49206 + pDestSecPathList = pDestParams->SecondaryPaths = pPathListTemp;
49208 + else
49210 + pDestSecPathList->next = pPathListTemp;
49211 + pDestSecPathList = pDestSecPathList->next;
49213 + strcpy (pDestSecPathList->Secondary, pSrcSecPathList->Secondary);
49214 + if (pSrcSecPathList->SecondaryPathParams != NULL)
49216 + if ((pDestSecPathList->SecondaryPathParams =
49217 + (LSP_PATH_SHARED_PARAMS *) XMALLOC (MTYPE_TE,
49218 + sizeof
49219 + (LSP_PATH_SHARED_PARAMS)))
49220 + == NULL)
49222 + zlog_info ("leaving UserLspAPI %s %d", __FILE__, __LINE__);
49223 + return CMD_SUCCESS;
49225 + memcpy (pDestSecPathList->SecondaryPathParams,
49226 + pSrcSecPathList->SecondaryPathParams,
49227 + sizeof (LSP_PATH_SHARED_PARAMS));
49229 + pSrcSecPathList = pSrcSecPathList->next;
49232 + else
49234 + pUserLsp->params.lsp_params.setup_priority =
49235 + pUserLsp->params.lsp_params.hold_priority = 4;
49237 + vty->index = pUserLsp;
49238 + return CMD_SUCCESS;
49241 +DEFUN (no_mpls_te_tunnel,
49242 + no_mpls_te_tunnel_cmd,
49243 + "no interface tunnel WORD",
49244 + "MPLS TE tunnel name\n" "Remove MPLS TE tunnel configuration\n")
49246 + USER_LSP *pCurrUserLsp;
49247 + SM_CALL_T *pCall;
49249 + strcpy (CurrentTunnelName, "");
49250 + if ((pCurrUserLsp = UserLspGet (argv[0])) != NULL)
49252 + pCurrUserLsp->params.lsp_params.disable = TRUE;
49253 + if ((pCall =
49254 + lsp_sm_sync_invoke (0, pCurrUserLsp,
49255 + USER_LSP_REQUEST_EVENT)) == NULL)
49257 + zlog_err ("\ncan not invoke sm %s %d", __FILE__, __LINE__);
49259 + else
49261 + zlog_info ("%s %d", __FILE__, __LINE__);
49262 + sm_call (pCall);
49265 + return CMD_SUCCESS;
49268 +DEFUN (show_mpls_te_tunnel,
49269 + show_mpls_te_tunnel_cmd,
49270 + "show mpls traffic-eng tunnel WORD", "MPLS TE Tunnel's name")
49272 + UserLspsDump (argv[0], vty);
49273 + return CMD_SUCCESS;
49276 +DEFUN (show_mpls_te_tunnels,
49277 + show_mpls_te_tunnels_cmd,
49278 + "show mpls traffic-eng tunnels", "Shows MPLS TE tunnels")
49280 + UserLspsDump (NULL, vty);
49281 + return CMD_SUCCESS;
49284 +DEFUN (mpls_te_tunnel_dest,
49285 + mpls_te_tunnel_dest_cmd,
49286 + "tunnel destination A.B.C.D",
49287 + "MPLS TE Tunnel's destination IP address")
49289 + USER_LSP *pUserLsp = vty->index;
49290 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params;
49291 + struct in_addr dest;
49292 + int ret;
49293 + ret = inet_aton (argv[0], &dest);
49294 + if (!ret)
49296 + vty_out (vty, "Please specify destination IP address %s", VTY_NEWLINE);
49297 + return CMD_WARNING;
49299 + pDestParams->to = ntohl (dest.s_addr);
49300 + return CMD_SUCCESS;
49303 +DEFUN (mpls_te_tunnel_bandwidth,
49304 + mpls_te_tunnel_bandwidth_cmd,
49305 + "tunnel mpls traffic-eng bandwidth <0-4294967295>",
49306 + "MPLS TE Tunnel's bandwidth")
49308 + USER_LSP *pUserLsp = vty->index;
49309 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params;
49310 + pDestParams->lsp_params.BW = atol (argv[0]);
49311 + return CMD_SUCCESS;
49314 +DEFUN (no_mpls_te_tunnel_bandwidth,
49315 + no_mpls_te_tunnel_bandwidth_cmd,
49316 + "no tunnel mpls traffic-eng bandwidth", "MPLS TE Tunnel's bandwidth")
49318 + USER_LSP *pUserLsp = vty->index;
49319 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params;
49320 + pDestParams->lsp_params.BW = 0;
49321 + return CMD_SUCCESS;
49324 +DEFUN (mpls_te_tunnel_sprio,
49325 + mpls_te_tunnel_sprio_cmd,
49326 + "tunnel mpls traffic-eng priority <0-7>",
49327 + "MPLS TE Tunnel's setup priority")
49329 + USER_LSP *pUserLsp = vty->index;
49330 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params;
49331 + pDestParams->lsp_params.setup_priority = atol (argv[0]);
49332 + pDestParams->lsp_params.hold_priority =
49333 + pDestParams->lsp_params.setup_priority;
49334 + return CMD_SUCCESS;
49337 +DEFUN (mpls_te_tunnel_shprio,
49338 + mpls_te_tunnel_shprio_cmd,
49339 + "tunnel mpls traffic-eng priority <0-7> <0-7>",
49340 + "MPLS TE Tunnel's setup priority" "MPLS TE Tunnel's hold priority")
49342 + USER_LSP *pUserLsp = vty->index;
49343 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params;
49344 + pDestParams->lsp_params.setup_priority = atol (argv[0]);
49345 + pDestParams->lsp_params.hold_priority = atol (argv[1]);
49346 + return CMD_SUCCESS;
49349 +DEFUN (no_mpls_te_tunnel_prio,
49350 + no_mpls_te_tunnel_prio_cmd,
49351 + "no tunnel mpls traffic-eng priority", "MPLS TE Tunnel's priority")
49353 + USER_LSP *pUserLsp = vty->index;
49354 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params;
49355 + pDestParams->lsp_params.hold_priority =
49356 + pDestParams->lsp_params.setup_priority = 4;
49357 + return CMD_SUCCESS;
49360 +DEFUN (mpls_te_tunnel_hop_limit,
49361 + mpls_te_tunnel_hop_limit_cmd,
49362 + "tunnel mpls traffic-eng hop-limit <0-255>",
49363 + "MPLS TE Tunnel's path hop limit")
49365 + USER_LSP *pUserLsp = vty->index;
49366 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params;
49367 + pDestParams->lsp_params.hop_limit = atol (argv[0]);
49368 + return CMD_SUCCESS;
49371 +DEFUN (no_mpls_te_tunnel_hop_limit,
49372 + no_mpls_te_tunnel_hop_limit_cmd,
49373 + "no tunnel mpls traffic-eng hop-limit",
49374 + "MPLS TE Tunnel's path hop limit")
49376 + USER_LSP *pUserLsp = vty->index;
49377 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params;
49378 + pDestParams->lsp_params.hop_limit = 0;
49379 + return CMD_SUCCESS;
49382 +DEFUN (mpls_te_tunnel_optimize_timer,
49383 + mpls_te_tunnel_optimize_timer_cmd,
49384 + "tunnel mpls traffic-eng optimize-timer <0-604800>",
49385 + "MPLS TE Tunnel's optimize timer")
49387 + USER_LSP *pUserLsp = vty->index;
49388 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params;
49389 + pDestParams->lsp_params.optimize_timer = atol (argv[0]);
49390 + return CMD_SUCCESS;
49393 +DEFUN (no_mpls_te_tunnel_optimize_timer,
49394 + no_mpls_te_tunnel_optimize_timer_cmd,
49395 + "no tunnel mpls traffic-eng optimize-timer",
49396 + "MPLS TE Tunnel's optimize timer")
49398 + USER_LSP *pUserLsp = vty->index;
49399 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params;
49400 + pDestParams->lsp_params.optimize_timer = 0;
49401 + return CMD_SUCCESS;
49404 +DEFUN (mpls_te_tunnel_record_route,
49405 + mpls_te_tunnel_record_route_cmd,
49406 + "tunnel mpls traffic-eng record-route",
49407 + "MPLS TE Tunnel's record route")
49409 + USER_LSP *pUserLsp = vty->index;
49410 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params;
49411 + pDestParams->lsp_params.record = 1;
49412 + return CMD_SUCCESS;
49415 +DEFUN (no_mpls_te_tunnel_record_route,
49416 + no_mpls_te_tunnel_record_route_cmd,
49417 + "no tunnel mpls traffic-eng record-route",
49418 + "MPLS TE Tunnel's record route")
49420 + USER_LSP *pUserLsp = vty->index;
49421 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params;
49422 + pDestParams->lsp_params.record = 0;
49423 + return CMD_SUCCESS;
49426 +#if 0 /* for now - no support for hexa input */
49427 +DEFUN (mpls_te_tunnel_affinity,
49428 + mpls_te_tunnel_affinity_cmd,
49429 + "tunnel mpls traffic-eng affinity <0-255>",
49430 + "MPLS TE Tunnel's resource affinity")
49432 + USER_LSP *pUserLsp = vty->index;
49433 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params;
49434 + pDestParams->lsp_params.affinity_properties = atol (argv[0]);
49435 + return CMD_SUCCESS;
49438 +DEFUN (no_mpls_te_tunnel_affinity,
49439 + no_mpls_te_tunnel_affinity_cmd,
49440 + "no tunnel mpls traffic-eng affinity",
49441 + "MPLS TE Tunnel's resource affinity")
49443 + USER_LSP *pUserLsp = vty->index;
49444 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params;
49445 + pDestParams->lsp_params.affinity_properties = 0;
49446 + return CMD_SUCCESS;
49448 +#endif
49450 +DEFUN (mpls_te_tunnel_retry_timer,
49451 + mpls_te_tunnel_retry_timer_cmd,
49452 + "tunnel mpls traffic-eng retry-timer <1-604800>",
49453 + "MPLS TE Tunnel's setup retry timer")
49455 + USER_LSP *pUserLsp = vty->index;
49456 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params;
49457 + pDestParams->retry_timer = atol (argv[0]);
49458 + return CMD_SUCCESS;
49461 +DEFUN (no_mpls_te_tunnel_retry_timer,
49462 + no_mpls_te_tunnel_retry_timer_cmd,
49463 + "no tunnel mpls traffic-eng retry-timer",
49464 + "MPLS TE Tunnel's setup retry timer")
49466 + USER_LSP *pUserLsp = vty->index;
49467 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params;
49468 + pDestParams->retry_timer = 0;
49469 + return CMD_SUCCESS;
49472 +DEFUN (mpls_te_tunnel_retry_limit,
49473 + mpls_te_tunnel_retry_limit_cmd,
49474 + "tunnel mpls traffic-eng retry-limit <0-4294967295>",
49475 + "MPLS TE Tunnel's setup retry attempts limit")
49477 + USER_LSP *pUserLsp = vty->index;
49478 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params;
49479 + pDestParams->retry_limit = atol (argv[0]);
49480 + return CMD_SUCCESS;
49483 +DEFUN (no_mpls_te_tunnel_retry_limit,
49484 + no_mpls_te_tunnel_retry_limit_cmd,
49485 + "no tunnel mpls traffic-eng retry-limit",
49486 + "MPLS TE Tunnel's setup retry attempts limit")
49488 + USER_LSP *pUserLsp = vty->index;
49489 + USER_LSP_PARAMS *pDestParams = &pUserLsp->params;
49490 + pDestParams->retry_limit = 0;
49491 + return CMD_SUCCESS;
49495 +DEFUN (show_mpls_te_links,
49496 + show_mpls_te_links_cmd, "show mpls traffic-eng links", "MPLS TE links")
49498 + rdb_te_links_dump (vty);
49499 + return CMD_SUCCESS;
49502 +DEFUN (show_mpls_te_path_cache,
49503 + show_mpls_te_path_cache_cmd,
49504 + "show mpls traffic-eng path-cache",
49505 + "MPLS TE CSPF calculated path cache")
49507 + rdb_path_dump (vty);
49508 + return CMD_SUCCESS;
49511 +DEFUN (show_mpls_te_remote_link,
49512 + show_mpls_te_remote_link_cmd,
49513 + "show mpls traffic-eng remote-link", "MPLS TE remote links cache")
49515 + rdb_remote_link_dump (vty);
49516 + return CMD_SUCCESS;
49519 +DEFUN (show_mpls_te_next_hop,
49520 + show_mpls_te_next_hop_cmd,
49521 + "show mpls traffic-eng next-hop", "MPLS TE next hops cache")
49523 + rdb_next_hop_dump (vty);
49524 + return CMD_SUCCESS;
49527 +DEFUN (show_mpls_te_configured_paths,
49528 + show_mpls_te_configured_paths_cmd,
49529 + "show mpls traffic-eng static-path", "MPLS TE configured static paths")
49531 + rdb_static_path_dump (NULL, vty);
49532 + return CMD_SUCCESS;
49535 +DEFUN (show_mpls_te_ip_2_rtr_id_map,
49536 + show_mpls_te_ip_2_rtr_id_map_cmd,
49537 + "show mpls traffic-eng ip2routerID",
49538 + "MPLS TE show I/F IP addresses to RouterIDs mapping")
49540 + rdb_remote_link_router_id_mapping_dump (vty);
49541 + return CMD_SUCCESS;
49545 +DEFUN (show_rsvp_te_psbs,
49546 + show_rsvp_te_psbs_cmd, "show rsvpte psbs", "RSVP TE PSBs")
49548 + PSB_KEY PsbKey;
49549 + memset (&PsbKey, 0, sizeof (PSB_KEY));
49550 + DumpPSB (&PsbKey, vty);
49551 + return CMD_SUCCESS;
49554 +DEFUN (show_rsvp_te_rsbs,
49555 + show_rsvp_te_rsbs_cmd, "show rsvpte rsbs", "RSVP TE RSBs")
49557 + RSB_KEY RsbKey;
49558 + memset (&RsbKey, 0, sizeof (RSB_KEY));
49559 + DumpRSB (&RsbKey, vty);
49560 + return CMD_SUCCESS;
49563 +DEFUN (show_rsvp_te_psb,
49564 + show_rsvp_te_psb_cmd, "show rsvpte psb A.B.C.D", "RSVP TE PSB")
49566 + PSB_KEY PsbKey;
49567 + struct in_addr dest;
49568 + int ret;
49569 + ret = inet_aton (argv[0], &dest);
49570 + if (!ret)
49572 + vty_out (vty, "Please specify destination IP address %s", VTY_NEWLINE);
49573 + return CMD_WARNING;
49575 + memset (&PsbKey, 0, sizeof (PSB_KEY));
49576 + PsbKey.Session.Dest = dest.s_addr;
49577 + DumpPSB (&PsbKey, vty);
49578 + return CMD_SUCCESS;
49581 +DEFUN (show_rsvp_te_rsb,
49582 + show_rsvp_te_rsb_cmd, "show rsvpte rsb A.B.C.D", "RSVP TE RSB ")
49584 + RSB_KEY RsbKey;
49585 + struct in_addr dest;
49586 + int ret;
49588 + ret = inet_aton (argv[0], &dest);
49589 + if (!ret)
49591 + vty_out (vty, "Please specify destination IP address %s", VTY_NEWLINE);
49592 + return CMD_WARNING;
49594 + memset (&RsbKey, 0, sizeof (RSB_KEY));
49595 + RsbKey.Session.Dest = dest.s_addr;
49596 + DumpRSB (&RsbKey, vty);
49597 + return CMD_SUCCESS;
49600 +DEFUN (show_rsvp_te_statistics,
49601 + show_rsvp_te_statistics_cmd,
49602 + "show rsvpte statistics", "RSVP TE statistics")
49604 + DumpRsvpStatistics (vty);
49605 + return CMD_SUCCESS;
49608 +void
49609 +rsvp_vty ()
49611 + install_node (&mpls_te_tunnel_node, DummyConfigWrite);
49612 + install_node (&mpls_te_conf_node, MPLS_TE_ConfigWrite);
49614 + /* Install ospf commands. */
49615 + install_element (VIEW_NODE, &show_mpls_te_tunnel_cmd);
49616 + install_element (VIEW_NODE, &show_mpls_te_tunnels_cmd);
49617 + install_element (VIEW_NODE, &show_mpls_te_links_cmd);
49618 + install_element (VIEW_NODE, &show_mpls_te_path_cache_cmd);
49619 + install_element (VIEW_NODE, &show_mpls_te_remote_link_cmd);
49620 + install_element (VIEW_NODE, &show_mpls_te_next_hop_cmd);
49621 + install_element (VIEW_NODE, &show_mpls_te_configured_paths_cmd);
49622 + install_element (VIEW_NODE, &show_mpls_te_ip_2_rtr_id_map_cmd);
49624 + install_element (ENABLE_NODE, &show_mpls_te_tunnel_cmd);
49625 + install_element (ENABLE_NODE, &show_mpls_te_tunnels_cmd);
49626 + install_element (ENABLE_NODE, &show_mpls_te_links_cmd);
49627 + install_element (ENABLE_NODE, &show_mpls_te_path_cache_cmd);
49628 + install_element (ENABLE_NODE, &show_mpls_te_remote_link_cmd);
49629 + install_element (ENABLE_NODE, &show_mpls_te_next_hop_cmd);
49630 + install_element (ENABLE_NODE, &show_mpls_te_configured_paths_cmd);
49631 + install_element (ENABLE_NODE, &show_mpls_te_ip_2_rtr_id_map_cmd);
49633 + install_element (CONFIG_NODE, &mpls_te_tunnel_cmd);
49634 + install_element (CONFIG_NODE, &no_mpls_te_tunnel_cmd);
49636 + install_default (MPLS_TE_TUNNEL_NODE);
49637 + install_element (MPLS_TE_TUNNEL_NODE, &mpls_te_tunnel_dest_cmd);
49638 + install_element (MPLS_TE_TUNNEL_NODE, &mpls_te_tunnel_bandwidth_cmd);
49639 + install_element (MPLS_TE_TUNNEL_NODE, &no_mpls_te_tunnel_bandwidth_cmd);
49640 + install_element (MPLS_TE_TUNNEL_NODE, &mpls_te_tunnel_sprio_cmd);
49641 + install_element (MPLS_TE_TUNNEL_NODE, &mpls_te_tunnel_shprio_cmd);
49642 + install_element (MPLS_TE_TUNNEL_NODE, &no_mpls_te_tunnel_prio_cmd);
49643 + install_element (MPLS_TE_TUNNEL_NODE, &mpls_te_tunnel_hop_limit_cmd);
49644 + install_element (MPLS_TE_TUNNEL_NODE, &no_mpls_te_tunnel_hop_limit_cmd);
49645 + install_element (MPLS_TE_TUNNEL_NODE, &mpls_te_tunnel_optimize_timer_cmd);
49646 + install_element (MPLS_TE_TUNNEL_NODE,
49647 + &no_mpls_te_tunnel_optimize_timer_cmd);
49648 + install_element (MPLS_TE_TUNNEL_NODE, &mpls_te_tunnel_record_route_cmd);
49649 + install_element (MPLS_TE_TUNNEL_NODE, &no_mpls_te_tunnel_record_route_cmd);
49650 +#if 0 /* for now - no support for hexa input */
49651 + install_element (MPLS_TE_TUNNEL_NODE, &mpls_te_tunnel_affinity_cmd);
49652 + install_element (MPLS_TE_TUNNEL_NODE, &no_mpls_te_tunnel_affinity_cmd);
49653 +#endif
49654 + install_element (MPLS_TE_TUNNEL_NODE, &mpls_te_tunnel_retry_timer_cmd);
49655 + install_element (MPLS_TE_TUNNEL_NODE, &no_mpls_te_tunnel_retry_timer_cmd);
49656 + install_element (MPLS_TE_TUNNEL_NODE, &mpls_te_tunnel_retry_limit_cmd);
49657 + install_element (MPLS_TE_TUNNEL_NODE, &no_mpls_te_tunnel_retry_limit_cmd);
49659 + install_element (VIEW_NODE, &show_rsvp_te_psbs_cmd);
49660 + install_element (ENABLE_NODE, &show_rsvp_te_psbs_cmd);
49661 + install_element (VIEW_NODE, &show_rsvp_te_rsbs_cmd);
49662 + install_element (ENABLE_NODE, &show_rsvp_te_rsbs_cmd);
49664 + install_element (VIEW_NODE, &show_rsvp_te_psb_cmd);
49665 + install_element (ENABLE_NODE, &show_rsvp_te_psb_cmd);
49666 + install_element (VIEW_NODE, &show_rsvp_te_rsb_cmd);
49667 + install_element (ENABLE_NODE, &show_rsvp_te_rsb_cmd);
49669 + install_element (VIEW_NODE, &show_rsvp_te_statistics_cmd);
49670 + install_element (ENABLE_NODE, &show_rsvp_te_statistics_cmd);
49672 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_vty.h quagga-mpls/rsvpd/rsvp_vty.h
49673 --- quagga/rsvpd/rsvp_vty.h 1969-12-31 18:00:00.000000000 -0600
49674 +++ quagga-mpls/rsvpd/rsvp_vty.h 2007-07-02 23:41:22.000000000 -0500
49675 @@ -0,0 +1,6 @@
49676 +#ifndef _QUAGGA_RSVP_VTY_H
49677 +#define _QUAGGA_RSVP_VTY_H
49679 +extern void rsvp_vty ();
49681 +#endif
49682 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_zebra.c quagga-mpls/rsvpd/rsvp_zebra.c
49683 --- quagga/rsvpd/rsvp_zebra.c 1969-12-31 18:00:00.000000000 -0600
49684 +++ quagga-mpls/rsvpd/rsvp_zebra.c 2008-02-23 23:03:41.000000000 -0600
49685 @@ -0,0 +1,533 @@
49687 + * Zebra connect library for RSVPd
49688 + * Copyright (C) 1997, 98, 99, 2000 Kunihiro Ishiguro, Toshiaki Takada
49690 + * This file is part of GNU Zebra.
49692 + * GNU Zebra is free software; you can redistribute it and/or modify it
49693 + * under the terms of the GNU General Public License as published by the
49694 + * Free Software Foundation; either version 2, or (at your option) any
49695 + * later version.
49697 + * GNU Zebra is distributed in the hope that it will be useful, but
49698 + * WITHOUT ANY WARRANTY; without even the implied warranty of
49699 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
49700 + * General Public License for more details.
49702 + * You should have received a copy of the GNU General Public License
49703 + * along with GNU Zebra; see the file COPYING. If not, write to the
49704 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
49705 + * Boston, MA 02111-1307, USA.
49706 + */
49708 +#include <zebra.h>
49710 +#include "thread.h"
49711 +#include "command.h"
49712 +#include "network.h"
49713 +#include "prefix.h"
49714 +#include "routemap.h"
49715 +#include "table.h"
49716 +#include "stream.h"
49717 +#include "memory.h"
49718 +#include "zclient.h"
49719 +#include "filter.h"
49720 +#include "plist.h"
49721 +#include "log.h"
49723 +#include "rsvp.h"
49724 +#include "te.h"
49726 +/* Zebra structure to hold current status. */
49727 +struct zclient *zclient = NULL;
49729 +/* For registering threads. */
49730 +extern struct thread_master *master;
49731 +struct in_addr router_id_zebra;
49733 +/* Router-id update message from zebra. */
49734 +static int
49735 +rsvp_router_id_update_zebra (int command, struct zclient *zclient,
49736 + zebra_size_t length)
49738 + struct prefix router_id;
49739 + char buf[128];
49740 + zebra_router_id_update_read (zclient->ibuf, &router_id);
49742 + prefix2str (&router_id, buf, sizeof (buf));
49743 + zlog_debug ("Zebra rcvd: router id update %s", buf);
49745 + router_id_zebra = router_id.u.prefix4;
49746 + rdb_set_router_id (router_id_zebra.s_addr);
49748 + return 0;
49751 +/* Inteface addition message from zebra. */
49752 +static int
49753 +rsvp_interface_add (int command, struct zclient *zclient, zebra_size_t length)
49755 + struct interface *ifp;
49757 + ifp = zebra_interface_add_read (zclient->ibuf);
49759 + zlog_debug ("Zebra: interface add %s index %d flags %ld metric %d mtu %d",
49760 + ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
49762 + if (EnableRsvpOnInterface (ifp->ifindex) != E_OK)
49764 + zlog_err ("cannot enable RSVP on I/F %d", ifp->ifindex);
49766 + else
49768 + zlog_debug (" RSVP enabled");
49771 + return 0;
49774 +static int
49775 +rsvp_interface_delete (int command, struct zclient *zclient,
49776 + zebra_size_t length)
49778 + struct interface *ifp;
49779 + struct stream *s;
49781 + s = zclient->ibuf;
49782 + /* zebra_interface_state_read() updates interface structure in iflist */
49783 + ifp = zebra_interface_state_read (s);
49785 + if (ifp == NULL)
49786 + return 0;
49788 + if (if_is_up (ifp))
49789 + zlog_warn ("Zebra: got delete of %s, but interface is still up",
49790 + ifp->name);
49792 + zlog_debug
49793 + ("Zebra: interface delete %s index %d flags %ld metric %d mtu %d",
49794 + ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
49796 + if (DisableRsvpOnInterface (ifp->ifindex) != E_OK)
49798 + zlog_err ("cannot disable RSVP on I/F %d", ifp->ifindex);
49800 + else
49802 + zlog_debug (" RSVP disabled");
49805 + return 0;
49808 +static struct interface *
49809 +zebra_interface_if_lookup (struct stream *s)
49811 + char ifname_tmp[INTERFACE_NAMSIZ];
49813 + /* Read interface name. */
49814 + stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
49816 + /* And look it up. */
49817 + return if_lookup_by_name_len (ifname_tmp,
49818 + strnlen (ifname_tmp, INTERFACE_NAMSIZ));
49821 +static int
49822 +rsvp_interface_state_up (int command, struct zclient *zclient,
49823 + zebra_size_t length)
49825 + struct interface *ifp;
49827 + ifp = zebra_interface_if_lookup (zclient->ibuf);
49829 + if (ifp == NULL)
49830 + return 0;
49832 + /* Interface is already up. */
49833 + if (if_is_operative (ifp))
49835 + /* Temporarily keep ifp values. */
49836 + struct interface if_tmp;
49837 + memcpy (&if_tmp, ifp, sizeof (struct interface));
49839 + zebra_interface_if_set_value (zclient->ibuf, ifp);
49841 + zlog_debug ("Zebra: Interface[%s] state update.", ifp->name);
49843 + if (if_tmp.bandwidth != ifp->bandwidth)
49845 + zlog_debug ("Zebra: Interface[%s] bandwidth change %d -> %d.",
49846 + ifp->name, if_tmp.bandwidth, ifp->bandwidth);
49848 + return 0;
49851 + zebra_interface_if_set_value (zclient->ibuf, ifp);
49853 + zlog_debug ("Zebra: Interface[%s] state change to up.", ifp->name);
49855 + return 0;
49858 +static int
49859 +rsvp_interface_state_down (int command, struct zclient *zclient,
49860 + zebra_size_t length)
49862 + struct interface *ifp;
49864 + ifp = zebra_interface_state_read (zclient->ibuf);
49866 + if (ifp == NULL)
49867 + return 0;
49869 + zlog_debug ("Zebra: Interface[%s] state change to down.", ifp->name);
49871 + return 0;
49874 +static int
49875 +rsvp_interface_address_add (int command, struct zclient *zclient,
49876 + zebra_size_t length)
49878 + struct connected *c;
49879 + char buf[128];
49881 + c = zebra_interface_address_read (command, zclient->ibuf);
49883 + if (c == NULL)
49884 + return 0;
49886 + prefix2str (c->address, buf, sizeof (buf));
49887 + zlog_debug ("Zebra: interface %s address add %s", c->ifp->name, buf);
49889 + zlog_info ("trying to add IP address %s", buf);
49891 + if (IfIpAdd (c->address->u.prefix4.s_addr, c->address->prefixlen) != E_OK)
49893 + zlog_err ("Cannot add IP address %s %d", __FILE__, __LINE__);
49895 + if (IpAddrSetByIfIndex (c->ifp->ifindex, c->address->u.prefix4.s_addr) !=
49896 + E_OK)
49898 + zlog_err ("Cannot set IP address %s %d", __FILE__, __LINE__);
49900 + if (IsRsvpEnabledOnIf (c->ifp->ifindex) == E_OK)
49902 + if (EnableRsvpOnInterface2 (c->ifp->ifindex) != E_OK)
49904 + zlog_err ("Cannot enable RSVP on I/F %d %s %d",
49905 + c->ifp->ifindex, __FILE__, __LINE__);
49909 + return 0;
49912 +static int
49913 +rsvp_interface_address_delete (int command, struct zclient *zclient,
49914 + zebra_size_t length)
49916 + struct connected *c;
49917 + char buf[128];
49919 + c = zebra_interface_address_read (command, zclient->ibuf);
49921 + if (c == NULL)
49922 + return 0;
49924 + prefix2str (c->address, buf, sizeof (buf));
49925 + zlog_debug ("Zebra: interface %s address delete %s", c->ifp->name, buf);
49927 + if (IfIpAddrDel (c->address->u.prefix4.s_addr, c->address->prefixlen) !=
49928 + E_OK)
49930 + zlog_err ("Cannot add IP address %s %d", __FILE__, __LINE__);
49932 + if (IpAddrSetByIfIndex (c->ifp->ifindex, 0) != E_OK)
49934 + zlog_err ("Cannot unset IP address %s %d", __FILE__, __LINE__);
49936 + DisableRsvpOnInterface (c->ifp->ifindex);
49938 + connected_free (c);
49940 + return 0;
49943 +/* Zebra route add and delete treatment. */
49944 +static int
49945 +rsvp_zebra_read_ipv4 (int command, struct zclient *zclient,
49946 + zebra_size_t length)
49948 + struct stream *s;
49949 + struct zapi_ipv4 api;
49950 + unsigned long ifindex;
49951 + struct in_addr nexthop;
49952 + struct prefix_ipv4 p;
49953 + int i;
49955 + s = zclient->ibuf;
49957 + zapi_ipv4_read (s, length, &api, &p);
49959 + if (IPV4_NET127 (ntohl (p.prefix.s_addr)))
49960 + return 0;
49962 + /* Nexthop, ifindex, distance, metric. */
49963 + if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
49965 + for (i = 0; i < api.nexthop_num; i++)
49967 + nexthop.s_addr = 0;
49968 + ifindex = 0;
49970 + if (CHECK_FLAG (api.nexthop[i].type, ZEBRA_NEXTHOP_IPV4))
49971 + nexthop.s_addr = api.nexthop[i].gw.ipv4.s_addr;
49973 + if (CHECK_FLAG (api.nexthop[i].type, ZEBRA_NEXTHOP_IFINDEX))
49974 + ifindex = api.nexthop[i].intf.index;
49976 + if (command == ZEBRA_IPV4_ROUTE_ADD)
49982 + return 0;
49986 +COMPONENT_LINK *
49987 +new_component_link ()
49989 + COMPONENT_LINK *pComponentLink;
49991 + if ((pComponentLink =
49992 + (COMPONENT_LINK *) XMALLOC (MTYPE_TE,
49993 + sizeof (COMPONENT_LINK))) == NULL)
49995 + zlog_err ("\n can not allocate memory %s %d", __FILE__, __LINE__);
49996 + return NULL;
49998 + pComponentLink->next = NULL;
49999 + return pComponentLink;
50002 +#if 0
50003 +static int
50004 +te_zebra_read_link (int command, struct zclient *zclient, zebra_size_t length)
50006 + struct stream *s;
50007 + struct zapi_te_link link;
50008 + s = zclient->ibuf;
50009 + zapi_te_link_read(s, &link);
50010 + switch(command)
50012 + case ZEBRA_TE_LINK_ADD:
50014 + TE_LINK *pTeLink;
50015 + COMPONENT_LINK *pComponentLink;
50016 + int ComponentLinksNumber = 1, i, j;
50017 + PATRICIA_PARAMS params;
50019 + if ((pTeLink = (TE_LINK *) XMALLOC (MTYPE_TE, sizeof (TE_LINK))) == NULL)
50021 + zlog_err ("\ncannnot allocate memory");
50022 + return;
50024 + pTeLink->component_links = NULL;
50025 + pTeLink->te_link_id = link->linkid;
50026 + pTeLink->type = PSC_PATH;
50027 + pTeLink->te_link_properties.TeMetric = link->metric;
50028 + pTeLink->te_link_properties.color_mask = link->color_mask;
50029 + pTeLink->te_link_properties.MaxLspBW = link->max_lsp_bw;
50030 + pTeLink->te_link_properties.MaxReservableBW = link->max_res_bw;
50032 + for (j = 0; j < 8; j++)
50033 + pTeLink->te_link_properties.ReservableBW[j] = 0;
50034 + for (i = 0; i < ComponentLinksNumber; i++)
50036 + if ((pComponentLink = new_component_link ()) == NULL)
50038 + zlog_err ("\ncan initiate component link %s %d", __FILE__,
50039 + __LINE__);
50040 + return;
50042 + params.key_size = sizeof (FRR_LABEL_ENTRY);
50043 + params.info_size = 0;
50044 + if (patricia_tree_init (&pComponentLink->ProtectionTree, &params) !=
50045 + E_OK)
50047 + zlog_err ("\ncannot initiate patricia tree (per SM) for FRR");
50048 + return;
50051 + params.key_size = sizeof (PSB_KEY);
50052 + params.info_size = 0;
50053 + if (patricia_tree_init (&pComponentLink->IngressProtectionTree, &params)
50054 + != E_OK)
50056 + zlog_err ("\ncannot initiate patricia tree (per SM) for FRR");
50057 + return;
50059 + pComponentLink->next = pTeLink->component_links;
50060 + pTeLink->component_links = pComponentLink;
50061 + pComponentLink->oifIndex = link->ifindex; /*pTeLink->te_link_id */
50062 + for (j = 0; j < 8; j++)
50064 + pComponentLink->ReservableBW[j] = link->reservable_bw[j];
50065 + pComponentLink->ConfiguredReservableBW[j] = link->reservable_bw[j];
50066 + pTeLink->te_link_properties.ReservableBW[j] +=
50067 + pComponentLink->ReservableBW[j];
50071 + if (rdb_add_te_link (pTeLink) != E_OK)
50073 + zlog_err ("\nCannot delete TE link");
50076 + break;
50077 + case ZEBRA_TE_LINK_DELETE:
50078 + if (rdb_del_te_link (link->linkid) != E_OK)
50080 + zlog_err ("\nCannot delete TE link");
50082 + break;
50083 + case ZEBRA_TE_LINK_UPDATE:
50084 + if (rdb_local_link_status_change (link->linkid, link->status) != E_OK)
50086 + zlog_err ("\nCannot set TE link down");
50089 + break;
50093 +static int
50094 +te_zebra_read_remote_link (int command, struct zclient *zclient, zebra_size_t length)
50096 + struct zapi_te_remote_link link;
50097 + struct stream *s;
50098 + s = zclient->ibuf;
50099 + zapi_te_remote_link_read(s, &link);
50100 +#if 0
50101 + switch (command)
50103 +case RemoteLsUpdate:
50105 + LINK_PROPERTIES LinkProperties;
50106 + int j;
50108 + LinkProperties.LinkTeMetric = link->metric;
50109 + LinkProperties.LinkColorMask = link->color_mask;
50110 + LinkProperties.LinkMaxLspBW = link->max_lsp_bw;
50111 + LinkProperties.LinkMaxReservableBW = link->max_res_bw;
50113 + for (j = 0; j < 8; j++)
50115 + LinkProperties.LinkReservableBW[j] = link->reservable_bw[j];
50118 + LinkProperties.LinkType = PSC_PATH;
50120 + if (rdb_link_state_update (link->from_node.s_addr, link->to_node.s_addr, &LinkProperties) != E_OK)
50122 + zlog_err ("\nFailure");
50125 +break;
50126 +case ConnectivityBroken:
50127 + if (rdb_connectivity_broken (link->from_node.s_addr, link->to_node.s_addr, PSC_PATH) != E_OK)
50129 + zlog_err ("\nfailed");
50131 +break;
50134 +#endif
50137 +static int
50138 +te_zebra_read_link2rtrid (int command, struct zclient *zclient, zebra_size_t length)
50140 + struct zapi_te_link2rtrid l2ri;
50141 + struct stream *s;
50142 + s = zclient->ibuf;
50143 + zapi_te_link2rtrid_read(s, &l2ri);
50144 + switch (command)
50146 + case ZEBRA_TE_LINK2RTRID_ADD:
50147 + if (rdb_remote_link_2_router_id_mapping (l2ri->linkid, l2ri->routerid.s_addr) != E_OK)
50149 + zlog_err ("Cannot map link with ip address %x to router with id %x",
50150 + l2ri->linkid, l2ri->routerid.s_addr);
50152 + break;
50153 + case ZEBRA_TE_LINK2RTRID_DELETE:
50154 + if (rdb_remote_link_2_router_id_mapping_withdraw (l2ri->linkid) != E_OK)
50156 + zlog_err ("Cannot withdraw mapping of link with ip address %x",
50157 + l2ri->linkid);
50159 + break;
50163 +static int
50164 +te_zebra_read_nexthop (int command, struct zclient *zclient, zebra_size_t length)
50166 + struct zapi_te_nexthop nh;
50167 + struct stream *s;
50168 + s = zclient->ibuf;
50169 + zapi_te_nexthop_read(s, &nh);
50170 + switch(command)
50172 + case ZEBRA_TE_NEXTHOP_ADD:
50173 + if (rdb_add_next_hop (nh->nh.gw.ipv4.s_addr, nh->linkid) != E_OK)
50175 + zlog_err ("\nCannot add next hop");
50177 + case ZEBRA_TE_NEXTHOP_DELETE:
50178 + if (rdb_del_next_hop (nh->nh.gw.ipv4.s_addr, nh->linkid) != E_OK)
50180 + zlog_err ("\nCannot delete Next Hop");
50185 +#endif
50188 +void
50189 +rsvp_zebra_init ()
50191 + /* Allocate zebra structure. */
50192 + zclient = zclient_new ();
50193 + zclient_init (zclient, ZEBRA_ROUTE_RSVP);
50194 + zclient->router_id_update = rsvp_router_id_update_zebra;
50195 + zclient->interface_add = rsvp_interface_add;
50196 + zclient->interface_delete = rsvp_interface_delete;
50197 + zclient->interface_up = rsvp_interface_state_up;
50198 + zclient->interface_down = rsvp_interface_state_down;
50199 + zclient->interface_address_add = rsvp_interface_address_add;
50200 + zclient->interface_address_delete = rsvp_interface_address_delete;
50201 + zclient->ipv4_route_add = rsvp_zebra_read_ipv4;
50202 + zclient->ipv4_route_delete = rsvp_zebra_read_ipv4;
50203 +#if 0
50204 + zclient->te_link_add = te_zebra_read_link;
50205 + zclient->te_link_delete = te_zebra_read_link;
50206 + zclient->te_link_update = te_zebra_read_link;
50207 + zclient->te_link_remote_update = te_zebra_read_remote_link;
50208 + zclient->te_link2rtrid_add = te_zebra_read_link2rtrid;
50209 + zclient->te_link2rtrid_delete = te_zebra_read_link2rtrid;
50210 + zclient->te_nexthop_add = te_zebra_read_nexthop;
50211 + zclient->te_nexthop_delete = te_zebra_read_nexthop;
50212 +#endif
50214 + zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, ZEBRA_ROUTE_TE);
50215 +#if 0
50216 + rdb_igp_hello();
50217 +#endif
50219 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/rsvp_zebra.h quagga-mpls/rsvpd/rsvp_zebra.h
50220 --- quagga/rsvpd/rsvp_zebra.h 1969-12-31 18:00:00.000000000 -0600
50221 +++ quagga-mpls/rsvpd/rsvp_zebra.h 2007-06-14 21:35:58.000000000 -0500
50222 @@ -0,0 +1,28 @@
50224 + * Zebra connect library for RSVPd
50225 + * Copyright (C) 1997, 98, 99, 2000 Kunihiro Ishiguro, Toshiaki Takada
50227 + * This file is part of GNU Zebra.
50229 + * GNU Zebra is free software; you can redistribute it and/or modify it
50230 + * under the terms of the GNU General Public License as published by the
50231 + * Free Software Foundation; either version 2, or (at your option) any
50232 + * later version.
50234 + * GNU Zebra is distributed in the hope that it will be useful, but
50235 + * WITHOUT ANY WARRANTY; without even the implied warranty of
50236 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
50237 + * General Public License for more details.
50239 + * You should have received a copy of the GNU General Public License
50240 + * along with GNU Zebra; see the file COPYING. If not, write to the
50241 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
50242 + * Boston, MA 02111-1307, USA.
50243 + */
50245 +#ifndef _ZEBRA_RSVP_ZEBRA_H
50246 +#define _ZEBRA_RSVP_ZEBRA_H
50248 +extern void rsvp_zebra_init (void);
50250 +#endif /* _ZEBRA_RSVP_ZEBRA_H */
50251 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_api.c quagga-mpls/rsvpd/te_api.c
50252 --- quagga/rsvpd/te_api.c 1969-12-31 18:00:00.000000000 -0600
50253 +++ quagga-mpls/rsvpd/te_api.c 2007-07-03 00:47:54.000000000 -0500
50254 @@ -0,0 +1,157 @@
50255 +/* Module: api.c
50256 + Contains: TE application in-process API functions
50257 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
50258 + */
50259 +#include "te.h"
50261 +#define MAX_FLOAT 40000000000.0
50263 +void
50264 +TE_RSVPTE_API_TransitReqAPI (TE_API_MSG * dmsg)
50266 + SM_T *pNewSm;
50267 + PATH_NOTIFICATION *pTransitRequest;
50268 + PSB_KEY PsbKey;
50269 + SM_CALL_T *pCall;
50271 + if ((pTransitRequest =
50272 + (PATH_NOTIFICATION *) XMALLOC (MTYPE_TE,
50273 + sizeof (PATH_NOTIFICATION))) == NULL)
50275 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
50276 + return;
50279 + memcpy (pTransitRequest, &dmsg->u.PathNotification,
50280 + sizeof (PATH_NOTIFICATION));
50282 + PsbKey = pTransitRequest->PsbKey;
50284 + pNewSm = sm_gen_alloc (0, TRANSIT_LSP_SM);
50285 + if (pNewSm == NULL)
50287 + zlog_err ("fatal %s %d\n", __FILE__, __LINE__);
50288 + return;
50290 + if ((pCall =
50291 + sm_gen_sync_event_send (pNewSm, TRANSIT_REQ_EVENT,
50292 + pTransitRequest)) == NULL)
50294 + zlog_err ("\ncan not invoke sm %s %d", __FILE__, __LINE__);
50295 + return;
50297 + sm_call (pCall);
50298 + return;
50301 +void
50302 +TE_IGP_API_PathAdd (void *pBuf, int Len)
50304 + char *p;
50305 + PATH *pPath;
50306 + IPV4_ADDR dest_ip;
50307 + TE_HOP *er_hops;
50308 + float PathMinReservableBW[8], PathMaxBW = MAX_FLOAT, PathMaxReservableBW = MAX_FLOAT; /*FIXME!! */
50309 + int hop_count, i, j, SumTeMetric = 0;
50310 + zlog_info ("PathAdd");
50313 + pBuf += sizeof (EVENTS_E);
50314 + Len -= sizeof (EVENTS_E);
50315 + p = pBuf;
50316 + dest_ip = *((int *) p);
50317 + p += sizeof (int);
50318 + Len -= sizeof (int);
50319 + if (Len % 56)
50321 + zlog_err
50322 + ("The payload after destination field is not %d-alligned %d %d",
50323 + Len % 56, Len, sizeof (TE_HOP));
50324 + return;
50326 + hop_count = Len / sizeof (TE_HOP);
50327 + pPath = (PATH *) XMALLOC (MTYPE_TE, sizeof (PATH));
50328 + if (pPath == NULL)
50330 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
50331 + return;
50333 + memset (pPath, 0, sizeof (PATH));
50334 + er_hops = (TE_HOP *) XMALLOC (MTYPE_TE, sizeof (TE_HOP) * hop_count);
50335 + if (er_hops == NULL)
50337 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
50338 + return;
50340 + for (i = 0; i < 8; i++)
50342 + PathMinReservableBW[i] = MAX_FLOAT;
50345 + for (i = 0; i < hop_count; i++)
50347 + er_hops[i].local_ip = *((int *) p);
50348 + p += sizeof (int);
50349 + er_hops[i].remote_ip = *((int *) p);
50350 + p += sizeof (int);
50351 + er_hops[i].MaxReservableBW = *((float *) p);
50352 + p += sizeof (float);
50353 + for (j = 0; j < 8; j++)
50355 + er_hops[i].ReservableBW[j] = *((float *) p);
50356 + p += sizeof (float);
50358 + er_hops[i].MaxLspBW = *((float *) p);
50359 + if (er_hops[i].MaxLspBW < PathMaxBW)
50360 + PathMaxBW = er_hops[i].MaxLspBW;
50361 + p += sizeof (float);
50363 + for (j = 0; j < 8; j++)
50365 + if (er_hops[i].ReservableBW[j] < PathMinReservableBW[j])
50366 + PathMinReservableBW[j] = er_hops[i].ReservableBW[j];
50368 + er_hops[i].te_metric = *((int *) p);
50369 + p += sizeof (int);
50370 + SumTeMetric += er_hops[i].te_metric;
50371 + er_hops[i].ColorMask = *((int *) p);
50372 + p += sizeof (int);
50373 + if (er_hops[i].MaxReservableBW < PathMaxReservableBW)
50374 + PathMaxReservableBW = er_hops[i].MaxReservableBW;
50376 + if (hop_count == 0)
50377 + er_hops = NULL;
50378 + pPath->u.er_hops = er_hops;
50379 + pPath->PathProperties.PathType = PSC_PATH;
50380 + pPath->PathProperties.PathHopCount = hop_count;
50381 + pPath->PathProperties.PathMaxLspBW = PathMaxBW;
50382 + pPath->PathProperties.PathMaxReservableBW = PathMaxReservableBW;
50384 + for (j = 0; j < 8; j++)
50385 + pPath->PathProperties.PathReservableBW[j] = PathMinReservableBW[j];
50387 + pPath->PathProperties.PathSumTeMetric = SumTeMetric;
50388 + pPath->destination = dest_ip;
50389 + if (rdb_add_mod_path (dest_ip, pPath) != E_OK)
50391 + zlog_err ("Cannot add path");
50395 +void
50396 +TE_IGP_API_ReadPathCash (void *pBuf, int Len)
50398 + IPV4_ADDR IpAddr;
50399 + int handle;
50400 + char *p;
50402 + pBuf += sizeof (EVENTS_E);
50403 + Len -= sizeof (EVENTS_E);
50404 + p = pBuf;
50406 + IpAddr = *((int *) p);
50407 + p += sizeof (int);
50408 + handle = *((int *) p);
50409 + p += sizeof (int);
50410 + CspfReply (IpAddr, (void *) handle);
50412 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_api.h quagga-mpls/rsvpd/te_api.h
50413 --- quagga/rsvpd/te_api.h 1969-12-31 18:00:00.000000000 -0600
50414 +++ quagga-mpls/rsvpd/te_api.h 2007-07-03 00:48:35.000000000 -0500
50415 @@ -0,0 +1,8 @@
50416 +#ifndef __TE_API_H__
50417 +#define __TE_API_H__
50419 +void TE_RSVPTE_API_TransitReqAPI (TE_API_MSG * dmsg);
50420 +void TE_IGP_API_ReadPathCash (void *pBuf, int Len);
50421 +void TE_IGP_API_PathAdd (void *pBuf, int Len);
50423 +#endif
50424 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_bw_man.c quagga-mpls/rsvpd/te_bw_man.c
50425 --- quagga/rsvpd/te_bw_man.c 1969-12-31 18:00:00.000000000 -0600
50426 +++ quagga-mpls/rsvpd/te_bw_man.c 2008-02-25 21:32:15.000000000 -0600
50427 @@ -0,0 +1,1408 @@
50428 +/* Module: bw_man.c
50429 + Contains: TE application bandwidth manager
50430 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
50431 + */
50432 +#include "te.h"
50433 +#include "te_cspf.h"
50435 +extern PATRICIA_TREE BwOwnersTree[8];
50436 +extern PATRICIA_TREE IfBwOwnersTree[8];
50437 +extern struct zclient *zclient;
50439 +typedef struct
50441 + uns32 IfIndex;
50442 + PSB_KEY PsbKey;
50443 +} IF_BW_KEY;
50445 +typedef struct
50447 + PATRICIA_NODE Node;
50448 + IF_BW_KEY if_bw_key;
50449 + float BW;
50450 +} IF_BW_DATA;
50452 +static void CancelBwAllocAtHigherPriorities (PSB_KEY * key,
50453 + uns32 TeLinkId,
50454 + COMPONENT_LINK * pComponentLink,
50455 + uns8 Priority);
50456 +static void CancelBwAllocAtLowerPriorities (PSB_KEY * key,
50457 + uns32 TeLinkId,
50458 + COMPONENT_LINK * pComponentLink,
50459 + uns8 Priority);
50460 +static void CancelBwAllocAtOtherPriorities (PSB_KEY * key,
50461 + uns32 TeLinkId,
50462 + COMPONENT_LINK * pComponentLink,
50463 + uns8 Priority);
50464 +static float PreemptTunnel (uns32 TeLinkId,
50465 + COMPONENT_LINK * pComponentLink,
50466 + uns8 Priority, uns8 PreemptorPrio, PSB_KEY * key);
50467 +static void GetEfficientBwAtHigherPriorities (PSB_KEY * key,
50468 + uns32 TeLinkId,
50469 + COMPONENT_LINK * pComponentLink,
50470 + uns8 Priority, float *BW);
50471 +static uns32 UpdateIfBwOwnerStructure (uns32 IfIndex, PSB_KEY * key, float BW,
50472 + uns8 Priority);
50473 +static BOOL BwPreemptionUseful (uns32 IfIndex, uns8 SetupPriority,
50474 + float RequiredBW, uns8 * PreemptedPriority,
50475 + float *MaximumPossibleBW);
50476 +static void AllocateBW (TE_LINK * pTeLink, COMPONENT_LINK * pComponentLink,
50477 + uns8 Priority, float BW);
50478 +static void ReleaseBW (TE_LINK * pTeLink, COMPONENT_LINK * pComponentLink,
50479 + uns8 Priority, float BW);
50480 +static void PreemptBW (COMPONENT_LINK * pComponentLink,
50481 + uns8 PreemptorPriority, uns8 PreemptedPriority,
50482 + float BW);
50484 +typedef struct
50486 + int Event;
50487 + BW_UPDATE_REQUEST BwUpdateReq;
50488 +} BW_UPDATE_MSG;
50490 +void
50491 +BwUpdateRequest2Igp (TE_LINK * pTeLink)
50493 +#if 0
50494 + struct zapi_te_link link;
50495 + int i;
50497 + memset(&link, 0, sizeof(struct zapi_te_link));
50498 + link.linkid = pTeLink->te_link_id;
50499 + link.max_res_bw = pTeLink->te_link_properties.MaxReservableBW;
50501 + for (i = 0; i < 8; i++)
50502 + link.reservable_bw[i] = pTeLink->te_link_properties.ReservableBW[i];
50504 + zapi_te_link_update(zclient, &link);
50505 +#endif
50508 +static void
50509 +CancelBwAllocAtHigherPriorities (PSB_KEY * key,
50510 + uns32 TeLinkId,
50511 + COMPONENT_LINK * pComponentLink,
50512 + uns8 Priority)
50514 + BW_OWNER_ENTRY *pBwOwnerEntry;
50515 + BW_OWNER_DATA *pBwOwnerData, *pBwOwnerDataPrev = NULL;
50516 + TE_LINK *pTeLink;
50517 + int j;
50519 + if (Priority == 0)
50520 + return;
50522 + if (rdb_get_te_link (TeLinkId, &pTeLink) != E_OK)
50524 + zlog_err ("\ncannot get TE link %s %d", __FILE__, __LINE__);
50525 + return;
50527 + for (j = 0; j < Priority; j++)
50529 + if ((pBwOwnerEntry =
50530 + (BW_OWNER_ENTRY *) patricia_tree_get (&BwOwnersTree[j],
50531 + (const uns8 *) key)) != NULL)
50533 + pBwOwnerData = pBwOwnerEntry->pBwOwnerData;
50534 + while (pBwOwnerData != NULL)
50536 + if ((pBwOwnerData->TeLinkId == TeLinkId) &&
50537 + (pBwOwnerData->OutIf == pComponentLink->oifIndex))
50539 + ReleaseBW (pTeLink, pComponentLink, Priority,
50540 + pBwOwnerData->BW + pBwOwnerData->PreAllocBW);
50541 + if (pBwOwnerEntry->pBwOwnerData == pBwOwnerData)
50542 + pBwOwnerEntry->pBwOwnerData =
50543 + pBwOwnerEntry->pBwOwnerData->next;
50544 + else
50545 + pBwOwnerDataPrev->next = pBwOwnerData->next;
50546 + XFREE (MTYPE_TE, pBwOwnerData);
50547 + if (pBwOwnerEntry->pBwOwnerData == NULL)
50549 + zlog_info ("\nBW Owners Entry will be deleted2");
50550 + if (patricia_tree_del
50551 + (&BwOwnersTree[j], &pBwOwnerEntry->Node) != E_OK)
50553 + zlog_err
50554 + ("\ncannot delete node from patricia %s %d",
50555 + __FILE__, __LINE__);
50557 + else
50558 + XFREE (MTYPE_TE, pBwOwnerEntry);
50560 + break;
50562 + pBwOwnerData = pBwOwnerData->next;
50568 +static void
50569 +CancelBwAllocAtLowerPriorities (PSB_KEY * key,
50570 + uns32 TeLinkId,
50571 + COMPONENT_LINK * pComponentLink,
50572 + uns8 Priority)
50574 + BW_OWNER_ENTRY *pBwOwnerEntry;
50575 + BW_OWNER_DATA *pBwOwnerData, *pBwOwnerDataPrev = NULL;
50576 + TE_LINK *pTeLink;
50577 + int j;
50579 + if (rdb_get_te_link (TeLinkId, &pTeLink) != E_OK)
50581 + zlog_err ("\ncannot get TE link %s %d", __FILE__, __LINE__);
50582 + return;
50584 + for (j = Priority + 1; j < 8; j++)
50586 + if ((pBwOwnerEntry =
50587 + (BW_OWNER_ENTRY *) patricia_tree_get (&BwOwnersTree[j],
50588 + (const uns8 *) key)) != NULL)
50590 + pBwOwnerData = pBwOwnerEntry->pBwOwnerData;
50591 + while (pBwOwnerData != NULL)
50593 + if ((pBwOwnerData->TeLinkId == TeLinkId) &&
50594 + (pBwOwnerData->OutIf == pComponentLink->oifIndex))
50596 + ReleaseBW (pTeLink, pComponentLink, Priority,
50597 + pBwOwnerData->BW + pBwOwnerData->PreAllocBW);
50598 + if (pBwOwnerEntry->pBwOwnerData == pBwOwnerData)
50599 + pBwOwnerEntry->pBwOwnerData =
50600 + pBwOwnerEntry->pBwOwnerData->next;
50601 + else
50602 + pBwOwnerDataPrev->next = pBwOwnerData->next;
50603 + XFREE (MTYPE_TE, pBwOwnerData);
50604 + if (pBwOwnerEntry->pBwOwnerData == NULL)
50606 + zlog_info ("\nBW Owners Entry will be deleted2");
50607 + if (patricia_tree_del
50608 + (&BwOwnersTree[j], &pBwOwnerEntry->Node) != E_OK)
50610 + zlog_err
50611 + ("\ncannot delete node from patricia %s %d",
50612 + __FILE__, __LINE__);
50614 + else
50615 + XFREE (MTYPE_TE, pBwOwnerEntry);
50617 + break;
50619 + pBwOwnerData = pBwOwnerData->next;
50625 +static void
50626 +CancelBwAllocAtOtherPriorities (PSB_KEY * key,
50627 + uns32 TeLinkId,
50628 + COMPONENT_LINK * pComponentLink,
50629 + uns8 Priority)
50631 + CancelBwAllocAtHigherPriorities (key, TeLinkId, pComponentLink, Priority);
50632 + CancelBwAllocAtLowerPriorities (key, TeLinkId, pComponentLink, Priority);
50633 + return;
50636 +static void
50637 +GetEfficientBwAtHigherPriorities (PSB_KEY * key,
50638 + uns32 TeLinkId,
50639 + COMPONENT_LINK * pComponentLink,
50640 + uns8 Priority, float *BW)
50642 + BW_OWNER_ENTRY *pBwOwnerEntry;
50643 + BW_OWNER_DATA *pBwOwnerData;
50644 + int j, i, k;
50645 + float AllocBW[8], AllocatedBW[8][8], ReservableBW[8], ReleasedBW = 0;
50647 + memset (AllocBW, 0, sizeof (AllocBW));
50648 + memcpy (AllocatedBW, pComponentLink->AllocatedBW, sizeof (AllocatedBW));
50649 + memcpy (ReservableBW, pComponentLink->ReservableBW, sizeof (ReservableBW));
50651 + for (j = 0; j < Priority; j++)
50653 + if ((pBwOwnerEntry =
50654 + (BW_OWNER_ENTRY *) patricia_tree_get (&BwOwnersTree[j],
50655 + (const uns8 *) key)) != NULL)
50657 + pBwOwnerData = pBwOwnerEntry->pBwOwnerData;
50659 + while (pBwOwnerData != NULL)
50661 + if ((pBwOwnerData->TeLinkId == TeLinkId) &&
50662 + (pBwOwnerData->OutIf == pComponentLink->oifIndex))
50664 + AllocBW[j] = pBwOwnerData->BW + pBwOwnerData->PreAllocBW;
50665 + break;
50667 + pBwOwnerData = pBwOwnerData->next;
50671 + for (k = 0; k < 8; k++)
50673 + for (i = 0; (i < 8) && (BW > 0); i++)
50675 + if (AllocatedBW[i][i] > 0)
50677 + ReleasedBW = 0;
50678 + if (AllocBW[k] >= AllocatedBW[i][i])
50680 + ReleasedBW = AllocatedBW[i][i];
50681 + ReservableBW[i] += AllocatedBW[i][i];
50682 + AllocBW[k] -= AllocatedBW[i][i];
50683 + AllocatedBW[i][i] = 0;
50685 + else
50687 + ReleasedBW = AllocBW[k];
50688 + ReservableBW[i] += AllocBW[k];
50689 + AllocatedBW[i][i] -= AllocBW[k];
50690 + AllocBW[k] = 0;
50692 + for (j = i + 1; (j < 8) && (ReleasedBW > 0); j++)
50694 + if (AllocatedBW[i][j] > 0)
50696 + if (ReleasedBW >= AllocatedBW[i][j])
50698 + AllocatedBW[j][j] += AllocatedBW[i][j];
50699 + ReleasedBW -= AllocatedBW[i][j];
50700 + AllocatedBW[i][j] = 0;
50702 + else
50704 + AllocatedBW[j][j] += ReleasedBW;
50705 + AllocatedBW[i][j] -= ReleasedBW;
50706 + ReleasedBW = 0;
50712 + if (ReleasedBW > 0)
50714 + for (; i < 8; i++)
50716 + if (AllocatedBW[i][i] > 0)
50718 + break;
50720 + if (pComponentLink->ConfiguredReservableBW[i] > ReservableBW[i])
50722 + if ((ReservableBW[i] + ReleasedBW) <=
50723 + pComponentLink->ConfiguredReservableBW[i])
50725 + ReservableBW[i] += ReleasedBW;
50727 + else
50729 + ReservableBW[i] =
50730 + pComponentLink->ConfiguredReservableBW[i];
50736 + if (ReservableBW[Priority] >= pComponentLink->ReservableBW[Priority])
50738 + *BW = ReservableBW[Priority] - pComponentLink->ReservableBW[Priority];
50740 + else
50742 + *BW = 0;
50744 + return;
50747 +static float
50748 +PreemptTunnel (uns32 TeLinkId,
50749 + COMPONENT_LINK * pComponentLink,
50750 + uns8 Priority, uns8 PreemptorPrio, PSB_KEY * key)
50752 + IF_BW_KEY if_bw_key;
50753 + IF_BW_DATA *pIfBwEntry;
50754 + PSB_KEY PsbKey;
50755 + TE_API_MSG Msg;
50756 + float BW = 0;
50757 + memset (&if_bw_key, 0, sizeof (IF_BW_KEY));
50758 + if_bw_key.IfIndex = pComponentLink->oifIndex;
50759 + if ((pIfBwEntry =
50760 + (IF_BW_DATA *) patricia_tree_getnext (&IfBwOwnersTree[Priority],
50761 + (const uns8 *) &if_bw_key)) !=
50762 + NULL)
50764 + PsbKey = pIfBwEntry->if_bw_key.PsbKey;
50765 + BW = pIfBwEntry->BW;
50766 + if (patricia_tree_del (&IfBwOwnersTree[Priority], &pIfBwEntry->Node) !=
50767 + E_OK)
50769 + zlog_err ("\ncannot delete node %s %d", __FILE__, __LINE__);
50771 + else
50773 + XFREE (MTYPE_TE, pIfBwEntry);
50775 + if (memcmp (&PsbKey, key, sizeof (PSB_KEY)) != 0)
50777 + Msg.NotificationType = PREEMPT_FLOW_CMD;
50778 + Msg.u.PreemptFlow.RsbKey.Session = PsbKey.Session;
50779 + if ((PsbKey.SenderTemplate.IpAddr != 0) ||
50780 + (PsbKey.SenderTemplate.LspId != 0))
50782 + Msg.u.PreemptFlow.FilterSpecValid = 1;
50783 + Msg.u.PreemptFlow.FilterSpec = PsbKey.SenderTemplate;
50785 + else
50787 + Msg.u.PreemptFlow.FilterSpecValid = 0;
50789 + PreemptBW (pComponentLink, PreemptorPrio, Priority, BW);
50792 + return BW;
50795 +static uns32
50796 +UpdateIfBwOwnerStructure (uns32 IfIndex, PSB_KEY * key, float BW,
50797 + uns8 Priority)
50799 + IF_BW_KEY if_bw_key;
50800 + IF_BW_DATA *pIfBwEntry;
50801 + memset (&if_bw_key, 0, sizeof (IF_BW_KEY));
50802 + if_bw_key.IfIndex = IfIndex;
50803 + if_bw_key.PsbKey = *key;
50804 + if ((pIfBwEntry =
50805 + (IF_BW_DATA *) patricia_tree_get (&IfBwOwnersTree[Priority],
50806 + (const uns8 *) &if_bw_key)) == NULL)
50808 + if ((pIfBwEntry =
50809 + (IF_BW_DATA *) XMALLOC (MTYPE_TE, sizeof (IF_BW_DATA))) == NULL)
50811 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
50812 + return E_ERR;
50814 + pIfBwEntry->if_bw_key.IfIndex = IfIndex;
50815 + pIfBwEntry->if_bw_key.PsbKey = *key;
50816 + pIfBwEntry->BW = BW;
50817 + pIfBwEntry->Node.key_info = (uns8 *) & pIfBwEntry->if_bw_key;
50818 + if (patricia_tree_add (&IfBwOwnersTree[Priority], &pIfBwEntry->Node) !=
50819 + E_OK)
50821 + zlog_err ("\ncannot add node to patricia tree %s %d", __FILE__,
50822 + __LINE__);
50823 + return E_ERR;
50826 + else
50828 + pIfBwEntry->BW = BW;
50830 + return E_OK;
50833 +static BOOL
50834 +BwPreemptionUseful (uns32 IfIndex, uns8 SetupPriority, float RequiredBW,
50835 + uns8 * PreemptedPriority, float *MaximumPossibleBW)
50837 + IF_BW_KEY if_bw_key;
50838 + IF_BW_DATA *pIfBwEntry;
50839 + int j;
50840 + zlog_info ("entering BwPreemptionUseful");
50841 + (*MaximumPossibleBW) = 0;
50842 + memset (&if_bw_key, 0, sizeof (IF_BW_KEY));
50843 + if_bw_key.IfIndex = IfIndex;
50844 + for (j = SetupPriority + 1; j < 8; j++)
50846 + while ((pIfBwEntry =
50847 + (IF_BW_DATA *) patricia_tree_getnext (&IfBwOwnersTree[j],
50848 + (const uns8 *)
50849 + &if_bw_key)) != NULL)
50851 + (*MaximumPossibleBW) += pIfBwEntry->BW;
50852 + if ((*MaximumPossibleBW) >= RequiredBW)
50854 + *PreemptedPriority = j;
50855 + zlog_info ("leaving BwPreemptionUseful+");
50856 + return TRUE;
50858 + if_bw_key = pIfBwEntry->if_bw_key;
50861 + zlog_info ("leaving BwPreemptionUseful-");
50862 + return FALSE;
50865 +void
50866 +TE_RSVPTE_API_BwReleaseMessage (TE_API_MSG * dmsg)
50868 + zlog_info
50869 + ("\nBW release If %x dest %x tunnel id %x ext tunnel id %x Priority %x",
50870 + dmsg->u.BwRelease.IfIndex, dmsg->u.BwRelease.PsbKey.Session.Dest,
50871 + dmsg->u.BwRelease.PsbKey.Session.TunnelId,
50872 + dmsg->u.BwRelease.PsbKey.Session.ExtTunelId, dmsg->u.BwRelease.HoldPrio);
50874 + if (DoRelease (&dmsg->u.BwRelease.PsbKey,
50875 + dmsg->u.BwRelease.IfIndex /* temporary */ ,
50876 + dmsg->u.BwRelease.IfIndex,
50877 + dmsg->u.BwRelease.HoldPrio /*??? */ ) != E_OK)
50879 + zlog_info ("\nBW release failed %s %d", __FILE__, __LINE__);
50881 + zlog_info ("\nAfter release...........");
50882 + return;
50885 +uns32
50886 +DoPreBwAllocation (PSB_KEY * key,
50887 + uns32 TeLinkId,
50888 + COMPONENT_LINK * pComponentLink,
50889 + float BW, uns8 HoldPriority)
50891 + BW_OWNER_ENTRY *pBwOwnerEntry;
50892 + BW_OWNER_DATA *pBwOwnerData;
50894 + /* First - register an allocation on the BW owners tree
50895 + BW owner is the session if SE reservation style or
50896 + Session and Sender if FF reservation style
50897 + BW owners tree serves for the prevention of the double accounting
50898 + Upon the Path message, existing reservations are found
50899 + Additional BW is attempted to be allocated on the links,
50900 + where reservation already exists */
50901 + zlog_info ("inside of DoPreAlloc Hold %x BW %f Dest %x TunnelId %x Src %x",
50902 + HoldPriority, BW, key->Session.Dest, key->Session.TunnelId,
50903 + key->Session.ExtTunelId, key->SenderTemplate.IpAddr,
50904 + key->SenderTemplate.LspId);
50905 + if ((pBwOwnerEntry =
50906 + (BW_OWNER_ENTRY *) patricia_tree_get (&BwOwnersTree[HoldPriority],
50907 + (const uns8 *) key)) == NULL)
50909 + if ((pBwOwnerEntry =
50910 + (BW_OWNER_ENTRY *) XMALLOC (MTYPE_TE,
50911 + sizeof (BW_OWNER_ENTRY))) == NULL)
50913 + zlog_err ("\nFailed to allocate memory %s %d", __FILE__, __LINE__);
50914 + return E_ERR;
50916 + pBwOwnerEntry->key = *key;
50917 + zlog_info ("\nBW owner entry creation %x %x %x %x %x...",
50918 + pBwOwnerEntry->key.Session.Dest,
50919 + pBwOwnerEntry->key.Session.TunnelId,
50920 + pBwOwnerEntry->key.Session.ExtTunelId,
50921 + pBwOwnerEntry->key.SenderTemplate.IpAddr,
50922 + pBwOwnerEntry->key.SenderTemplate.LspId);
50923 + pBwOwnerEntry->Node.key_info = (uns8 *) & pBwOwnerEntry->key;
50924 + zlog_info ("\ninside of DoPreAlloc adding to %x", HoldPriority);
50925 + if (patricia_tree_add (&BwOwnersTree[HoldPriority],
50926 + &pBwOwnerEntry->Node) != E_OK)
50928 + zlog_err ("\nFailed to allocate memory %s %d", __FILE__, __LINE__);
50929 + return E_ERR;
50932 + else
50933 + zlog_info ("\nBW owner entry found %x %x %x %x %x...",
50934 + key->Session.Dest,
50935 + key->Session.TunnelId,
50936 + key->Session.ExtTunelId,
50937 + key->SenderTemplate.IpAddr, key->SenderTemplate.LspId);
50938 + /* however, pBwOwnerEntry points on new or existing BW entry now
50939 + find the existing reservation */
50940 + pBwOwnerData = pBwOwnerEntry->pBwOwnerData;
50941 + while (pBwOwnerData != NULL)
50943 + if ((pBwOwnerData->TeLinkId == TeLinkId) &&
50944 + (pBwOwnerData->OutIf == pComponentLink->oifIndex))
50946 + if (pBwOwnerData->BW <= BW)
50948 + if ((pBwOwnerData->PreAllocBW + pBwOwnerData->BW) >= BW)
50950 + if (pBwOwnerData->PreAllocBW <= BW)
50952 + te_stop_timer (&pBwOwnerData->BwHoldTimer);
50953 + pBwOwnerData->BwHoldTimer.data.bw_hold_data.BW +=
50954 + (BW - pBwOwnerData->PreAllocBW);
50955 + pBwOwnerData->PreAllocBW +=
50956 + (BW - pBwOwnerData->PreAllocBW);
50957 + if (te_start_timer
50958 + (&pBwOwnerData->BwHoldTimer, BW_HOLD_EXPIRY,
50959 + 30) != E_OK)
50961 + zlog_err ("\ncannot start BW hold timer %s %d",
50962 + __FILE__, __LINE__);
50965 + else
50966 + { /* just resttart the timer */
50967 + te_stop_timer (&pBwOwnerData->BwHoldTimer);
50968 + if (te_start_timer
50969 + (&pBwOwnerData->BwHoldTimer, BW_HOLD_EXPIRY,
50970 + 30) != E_OK)
50972 + zlog_err ("\ncannot start BW hold timer %s %d",
50973 + __FILE__, __LINE__);
50977 + else
50979 + if (BW <=
50980 + (pComponentLink->ReservableBW[HoldPriority] +
50981 + (pBwOwnerData->PreAllocBW + pBwOwnerData->BW)))
50983 + float delta;
50984 + delta =
50985 + BW - (pBwOwnerData->PreAllocBW + pBwOwnerData->BW);
50987 + te_stop_timer (&pBwOwnerData->BwHoldTimer);
50989 + pBwOwnerData->PreAllocBW += delta;
50990 + pBwOwnerData->BwHoldTimer.data.bw_hold_data.BW += delta;
50992 + if (te_start_timer
50993 + (&pBwOwnerData->BwHoldTimer, BW_HOLD_EXPIRY,
50994 + 30) != E_OK)
50996 + zlog_err ("\ncannot start BW hold timer %s %d",
50997 + __FILE__, __LINE__);
50999 + else
51001 + TE_LINK *pTeLink = NULL;
51003 + if (rdb_get_te_link (TeLinkId, &pTeLink) != E_OK)
51005 + zlog_err ("\ncannot get TE link %s %d",
51006 + __FILE__, __LINE__);
51007 + return E_ERR;
51009 + AllocateBW (pTeLink, pComponentLink, HoldPriority,
51010 + delta);
51011 + rdb_te_link_max_lsp_bw_calc (pTeLink);
51012 + BwUpdateRequest2Igp (pTeLink);
51015 + else
51017 + zlog_err
51018 + ("CALCULATION ERROR: expected to find BW %f %f !!!",
51019 + BW, pComponentLink->ReservableBW[HoldPriority]);
51020 + zlog_err
51021 + ("TE link id %x OutIf %x dest %x tunnel %x ext tunnel %x lsp id %x",
51022 + TeLinkId, pComponentLink->oifIndex,
51023 + key->Session.Dest, key->Session.TunnelId,
51024 + key->Session.ExtTunelId, key->SenderTemplate.LspId);
51025 + return E_ERR;
51029 + if (UpdateIfBwOwnerStructure (pComponentLink->oifIndex,
51030 + key,
51031 + pBwOwnerData->PreAllocBW +
51032 + pBwOwnerData->BW,
51033 + HoldPriority) != E_OK)
51035 + zlog_err ("\ncannot update IfBwOwnerStrucutre %s %d", __FILE__,
51036 + __LINE__);
51037 + return E_ERR;
51039 + zlog_info ("\ninside of %x...", pComponentLink->oifIndex);
51040 + return E_OK;
51042 + pBwOwnerData = pBwOwnerData->next;
51044 + if (pComponentLink->ReservableBW[HoldPriority] < BW)
51046 + zlog_err ("\nCALCULATION ERROR: expected to find BW %f %f !!!",
51047 + BW, pComponentLink->ReservableBW[HoldPriority]);
51048 + zlog_err
51049 + ("\nTE link id %x OutIf %x dest %x tunnel %x ext tunnel %x lsp id %x",
51050 + TeLinkId, pComponentLink->oifIndex, key->Session.Dest,
51051 + key->Session.TunnelId, key->Session.ExtTunelId,
51052 + key->SenderTemplate.LspId);
51053 + return E_ERR;
51055 + /* BW reservation does not exist on the particular TE link and If */
51056 + if ((pBwOwnerData =
51057 + (BW_OWNER_DATA *) XMALLOC (MTYPE_TE, sizeof (BW_OWNER_DATA))) == NULL)
51059 + zlog_err ("\nFailed to allocate memory %s %d", __FILE__, __LINE__);
51060 + return E_ERR;
51062 + pBwOwnerData->next = pBwOwnerEntry->pBwOwnerData;
51063 + pBwOwnerEntry->pBwOwnerData = pBwOwnerData;
51064 + pBwOwnerData->BW = 0;
51065 + pBwOwnerData->PreAllocBW = BW;
51066 + pBwOwnerData->OutIf = pComponentLink->oifIndex;
51067 + pBwOwnerData->TeLinkId = TeLinkId;
51069 + pBwOwnerData->BwHoldTimer.data.bw_hold_data.key = *key;
51070 + pBwOwnerData->BwHoldTimer.data.bw_hold_data.handle = (uns32) pBwOwnerData;
51071 + pBwOwnerData->BwHoldTimer.data.bw_hold_data.TeLinkId = TeLinkId;
51072 + pBwOwnerData->BwHoldTimer.data.bw_hold_data.OutIf =
51073 + pComponentLink->oifIndex;
51074 + pBwOwnerData->BwHoldTimer.data.bw_hold_data.BW = BW;
51075 + pBwOwnerData->BwHoldTimer.data.bw_hold_data.Priority = HoldPriority;
51076 + if (te_start_timer (&pBwOwnerData->BwHoldTimer, BW_HOLD_EXPIRY, 30) != E_OK)
51078 + zlog_err ("\ncannot start BW hold timer %s %d", __FILE__, __LINE__);
51080 + else
51082 + TE_LINK *pTeLink = NULL;
51084 + if (rdb_get_te_link (TeLinkId, &pTeLink) != E_OK)
51086 + zlog_err ("\ncannot get TE link %s %d", __FILE__, __LINE__);
51088 + zlog_info ("calling ALLOCATE");
51089 + AllocateBW (pTeLink, pComponentLink, HoldPriority, BW);
51090 + rdb_te_link_max_lsp_bw_calc (pTeLink);
51091 + BwUpdateRequest2Igp (pTeLink);
51093 + if (UpdateIfBwOwnerStructure
51094 + (pComponentLink->oifIndex, key, BW, HoldPriority) != E_OK)
51096 + zlog_err ("cannot update IfBwOwnerStructure %s %d", __FILE__, __LINE__);
51097 + return E_ERR;
51099 + return E_OK;
51102 +uns32
51103 +CalcActualAlloc (PSB_KEY * key,
51104 + uns32 TeLinkId,
51105 + COMPONENT_LINK * pComponentLink,
51106 + float *BW,
51107 + uns8 SetupPriority,
51108 + uns8 HoldPriority, uns8 * PreemptedPriority)
51110 + BW_OWNER_ENTRY *pBwOwnerEntry;
51111 + BW_OWNER_DATA *pBwOwnerData;
51112 + float BwAtHigherPriority;
51114 + GetEfficientBwAtHigherPriorities (key, TeLinkId, pComponentLink,
51115 + HoldPriority, &BwAtHigherPriority);
51117 + zlog_info ("\n%x %x %x %x %f",
51118 + key->Session.Dest,
51119 + key->Session.TunnelId,
51120 + key->Session.ExtTunelId,
51121 + key->SenderTemplate.LspId, BwAtHigherPriority);
51123 + if ((pBwOwnerEntry =
51124 + (BW_OWNER_ENTRY *) patricia_tree_get (&BwOwnersTree[HoldPriority],
51125 + (const uns8 *) key)) != NULL)
51127 + pBwOwnerData = pBwOwnerEntry->pBwOwnerData;
51128 + while (pBwOwnerData != NULL)
51130 + if ((pBwOwnerData->TeLinkId == TeLinkId) &&
51131 + (pBwOwnerData->OutIf == pComponentLink->oifIndex))
51133 + if ((pBwOwnerData->PreAllocBW + pBwOwnerData->BW +
51134 + BwAtHigherPriority) >= *BW)
51136 + zlog_info ("Additional allocation is not required: %f %f",
51137 + pBwOwnerData->PreAllocBW + pBwOwnerData->BW,
51138 + *BW);
51139 + *BW = 0;
51140 + return E_OK;
51142 + else if ((pComponentLink->ReservableBW[SetupPriority] +
51143 + pBwOwnerData->PreAllocBW + pBwOwnerData->BW +
51144 + BwAtHigherPriority) >= *BW)
51146 + zlog_info
51147 + ("Reservable#%f, alloc %f and higher prio alloc %f",
51148 + pComponentLink->ReservableBW[SetupPriority],
51149 + pBwOwnerData->PreAllocBW + pBwOwnerData->BW,
51150 + BwAtHigherPriority);
51151 + *BW =
51152 + *BW - (pBwOwnerData->PreAllocBW + pBwOwnerData->BW +
51153 + BwAtHigherPriority);
51154 + return E_OK;
51156 + else
51158 + float RequiredBW =
51159 + *BW - (pComponentLink->ReservableBW[SetupPriority] +
51160 + pBwOwnerData->PreAllocBW + pBwOwnerData->BW);
51161 + uns8 Preempted;
51162 + float MaximumPossibleBW;
51163 + /* checking for bumping possibilities */
51164 + if (BwPreemptionUseful
51165 + (pComponentLink->oifIndex, SetupPriority, RequiredBW,
51166 + &Preempted, &MaximumPossibleBW) == TRUE)
51168 + zlog_info
51169 + ("Preemption is useful. Priority2BePreempted %x Currently %x",
51170 + Preempted, *PreemptedPriority);
51171 + if (*PreemptedPriority <= Preempted)
51173 + *PreemptedPriority = Preempted;
51175 + *BW = pComponentLink->ReservableBW[SetupPriority];
51176 + return E_OK;
51178 + else
51180 + zlog_info ("Preemption will not help %s %d", __FILE__,
51181 + __LINE__);
51182 + return E_ERR;
51186 + pBwOwnerData = pBwOwnerData->next;
51189 + else
51190 + zlog_info ("First time pre-allocation...");
51192 + if ((pComponentLink->ReservableBW[SetupPriority] + BwAtHigherPriority) >=
51193 + *BW)
51195 + if (*BW > BwAtHigherPriority)
51197 + zlog_info ("Reservable#%f BW at Higher priority#%f, required %f",
51198 + pComponentLink->ReservableBW[SetupPriority],
51199 + BwAtHigherPriority, *BW);
51200 + *BW -= BwAtHigherPriority;
51202 + else
51204 + zlog_info
51205 + ("Reservable#%f BW at Lower priority#%f, required %f (actually 0)",
51206 + pComponentLink->ReservableBW[SetupPriority], BwAtHigherPriority,
51207 + *BW);
51208 + *BW = 0;
51210 + return E_OK;
51212 + else
51214 + float RequiredBW = *BW - pComponentLink->ReservableBW[SetupPriority];
51215 + uns8 Preempted;
51216 + float MaximumPossibleBW = 0;
51217 + /* checking for bumping possibilities */
51218 + if (BwPreemptionUseful
51219 + (pComponentLink->oifIndex, SetupPriority, RequiredBW, &Preempted,
51220 + &MaximumPossibleBW) == TRUE)
51222 + zlog_info ("Preemption will help: Required#%f PreemptedPrio %x %f",
51223 + RequiredBW, Preempted,
51224 + pComponentLink->ReservableBW[SetupPriority]);
51225 + if (*PreemptedPriority <= Preempted)
51227 + *PreemptedPriority = Preempted;
51229 + *BW = pComponentLink->ReservableBW[SetupPriority];
51230 + return E_OK;
51232 + else
51233 + return E_ERR;
51235 + return E_ERR;
51238 +uns32
51239 +TE_RSVPTE_API_DoAllocation (PSB_KEY * key,
51240 + uns32 TeLinkId,
51241 + uns32 OutIfIndex,
51242 + float BW,
51243 + uns8 SetupPriority,
51244 + uns8 HoldPriority, float *MaximumPossibleBW)
51246 + BW_OWNER_ENTRY *pBwOwnerEntry;
51247 + BW_OWNER_DATA *pBwOwnerData;
51248 + COMPONENT_LINK *pComponentLink = NULL;
51249 + TE_LINK *pTeLink = NULL;
51250 + float BwAtHigherPriority;
51252 + zlog_info
51253 + ("inside of DoAllocation BW %f Dest %x tunnel %x source %x %x LSP %x HoldPrio %x SetupPrio %x ...",
51254 + BW, key->Session.Dest, key->Session.TunnelId, key->Session.ExtTunelId,
51255 + key->SenderTemplate.IpAddr, key->SenderTemplate.LspId, HoldPriority,
51256 + SetupPriority);
51257 + zlog_info ("TE Link ID %d OutIfIndex %d", TeLinkId, OutIfIndex);
51259 + /* First - register an allocation on the BW owners tree
51260 + BW owner is the session if SE reservation style or
51261 + Session and Sender if FF reservation style
51262 + BW owners tree serves for the prevention of the double accounting
51263 + Upon the Path message, existing reservations are found
51264 + Additional BW is attempted to be allocated on the links,
51265 + where reservation already exists */
51266 + if (rdb_get_component_link (TeLinkId, OutIfIndex, &pComponentLink) != E_OK)
51268 + zlog_err ("\ncannot get component link %s %d", __FILE__, __LINE__);
51269 + return E_ERR;
51271 + if (rdb_get_te_link (TeLinkId, &pTeLink) != E_OK)
51273 + zlog_err ("\ncannot get TE link %s %d", __FILE__, __LINE__);
51274 + return E_ERR;
51276 + if ((pBwOwnerEntry =
51277 + (BW_OWNER_ENTRY *) patricia_tree_get (&BwOwnersTree[HoldPriority],
51278 + (const uns8 *) key)) != NULL)
51280 + pBwOwnerData = pBwOwnerEntry->pBwOwnerData;
51281 + while (pBwOwnerData != NULL)
51283 + if ((pBwOwnerData->TeLinkId == TeLinkId) &&
51284 + (pBwOwnerData->OutIf == OutIfIndex))
51286 + te_stop_timer (&pBwOwnerData->BwHoldTimer);
51287 + zlog_info
51288 + ("BW %f pBwOwnerData->BW %f pBwOwnerData->PreAlloc %f SetupPrio %x HoldPrio %x %s %d",
51289 + BW, pBwOwnerData->BW, pBwOwnerData->PreAllocBW,
51290 + SetupPriority, HoldPriority, __FILE__, __LINE__);
51291 + if (pBwOwnerData->BW > BW) /* is this BW decrease ? */
51293 + zlog_info ("res BW %f updt BW %f resbl BW %f",
51294 + pBwOwnerData->BW, BW,
51295 + pComponentLink->ReservableBW[HoldPriority]);
51297 + ReleaseBW (pTeLink, pComponentLink, HoldPriority,
51298 + pBwOwnerData->BW - BW);
51299 + pBwOwnerData->BW = BW;
51300 + pBwOwnerData->PreAllocBW = 0;
51302 + else
51304 + if (BW >= (pBwOwnerData->PreAllocBW + pBwOwnerData->BW))
51306 + float DeltaBW =
51307 + BW - (pBwOwnerData->PreAllocBW + pBwOwnerData->BW);
51308 + zlog_info ("DeltaBW %f PreAlloc %f Alloc %f BW %f",
51309 + DeltaBW, pBwOwnerData->PreAllocBW,
51310 + pBwOwnerData->BW, BW);
51312 + zlog_info
51313 + ("Required BW#%f is greater than allocated#%f", BW,
51314 + (pBwOwnerData->PreAllocBW + pBwOwnerData->BW));
51315 + GetEfficientBwAtHigherPriorities (key, TeLinkId,
51316 + pComponentLink,
51317 + HoldPriority,
51318 + &BwAtHigherPriority);
51319 + zlog_info ("At higher priorities #%x",
51320 + BwAtHigherPriority);
51321 + if (DeltaBW < BwAtHigherPriority)
51323 + zlog_info
51324 + ("It is enough to release own BW at higher priorities");
51325 + CancelBwAllocAtHigherPriorities (key, TeLinkId,
51326 + pComponentLink,
51327 + HoldPriority);
51328 + AllocateBW (pTeLink, pComponentLink, HoldPriority,
51329 + DeltaBW);
51331 + else if ((DeltaBW + BwAtHigherPriority) <=
51332 + pComponentLink->ReservableBW[HoldPriority])
51334 + zlog_info
51335 + ("Releasing own BW at higher priorities, allocating#%x",
51336 + DeltaBW - BwAtHigherPriority);
51337 + DeltaBW -= BwAtHigherPriority;
51338 + /* cancel BW allocations at lower priorities */
51339 + CancelBwAllocAtHigherPriorities (key, TeLinkId,
51340 + pComponentLink,
51341 + HoldPriority);
51342 + /* now take remaining BW from this priority should be sufficient */
51343 + AllocateBW (pTeLink, pComponentLink, HoldPriority,
51344 + DeltaBW);
51346 + else
51348 + uns8 PreemptedPriority;
51349 + zlog_info
51350 + ("BW can be allocated if only preemption helps");
51351 + /* try to get BW from lowest priority */
51352 + if (BwPreemptionUseful
51353 + (pComponentLink->oifIndex, SetupPriority,
51354 + DeltaBW, &PreemptedPriority,
51355 + MaximumPossibleBW) == TRUE)
51357 + uns8 Prio = 7;
51358 + zlog_info
51359 + ("Preemption will help. Trying to release #%f",
51360 + DeltaBW);
51361 + while (DeltaBW > 0)
51363 + float FoundBW;
51365 + if ((FoundBW = PreemptTunnel (TeLinkId,
51366 + pComponentLink,
51367 + Prio,
51368 + HoldPriority,
51369 + key)) == 0)
51371 + if (Prio == (SetupPriority + 1))
51373 + zlog_err ("Algorithmic error %s %d",
51374 + __FILE__, __LINE__);
51375 + return E_ERR;
51377 + else
51379 + Prio--;
51382 + DeltaBW -= FoundBW;
51385 + else
51387 + (*MaximumPossibleBW) +=
51388 + pBwOwnerData->PreAllocBW + pBwOwnerData->BW;
51389 + zlog_err ("cannot get enough BW %s %d",
51390 + __FILE__, __LINE__);
51391 + return E_ERR;
51394 + pBwOwnerData->PreAllocBW = 0;
51395 + pBwOwnerData->BW = BW;
51397 + else
51399 + zlog_info
51400 + ("BW, allocated#%f and pre-allocated#%f is greater than required#%f",
51401 + pBwOwnerData->BW, pBwOwnerData->PreAllocBW, BW);
51402 + pBwOwnerData->PreAllocBW =
51403 + (pBwOwnerData->PreAllocBW + pBwOwnerData->BW) - BW;
51404 + pBwOwnerData->BwHoldTimer.data.bw_hold_data.BW =
51405 + pBwOwnerData->PreAllocBW;
51406 + if (te_start_timer
51407 + (&pBwOwnerData->BwHoldTimer, BW_HOLD_EXPIRY,
51408 + 30) != E_OK)
51410 + zlog_err ("\ncannot start BW hold timer %s %d",
51411 + __FILE__, __LINE__);
51413 + pBwOwnerData->BW = BW;
51416 + /* if we're here, allocation succeeded */
51417 + /* cancel BW allocation at other priorities */
51418 + CancelBwAllocAtOtherPriorities (key, TeLinkId, pComponentLink,
51419 + HoldPriority);
51420 + rdb_te_link_max_lsp_bw_calc (pTeLink);
51421 + BwUpdateRequest2Igp (pTeLink);
51422 + /* Update If-BW owners structure */
51423 + if (UpdateIfBwOwnerStructure
51424 + (pComponentLink->oifIndex, key, BW, HoldPriority) != E_OK)
51426 + zlog_err ("\ncannot update IfBwOwnerStructure %s %d",
51427 + __FILE__, __LINE__);
51428 + return E_ERR;
51430 + return E_OK;
51432 + pBwOwnerData = pBwOwnerData->next;
51434 + zlog_info ("Expected BW owner data is not found.");
51436 + if (pComponentLink->ReservableBW[SetupPriority] < BW)
51438 + uns8 Preempted;
51439 + if (BwPreemptionUseful
51440 + (pComponentLink->oifIndex, SetupPriority, BW, &Preempted,
51441 + MaximumPossibleBW) == FALSE)
51443 + zlog_info ("cannot allocate BW exhausted %s %d", __FILE__,
51444 + __LINE__);
51445 + return E_ERR;
51449 + else
51451 + zlog_info
51452 + ("expected BW owner (Session) %x %x %x Prio %x is not found on the patricia tree %s %d",
51453 + key->Session.Dest, key->Session.TunnelId, key->Session.ExtTunelId,
51454 + HoldPriority, __FILE__, __LINE__);
51456 + if (pComponentLink->ReservableBW[SetupPriority] < BW)
51458 + /* try to get BW from lowest priority */
51459 + uns8 Preempted;
51460 + if (BwPreemptionUseful
51461 + (pComponentLink->oifIndex, SetupPriority, BW, &Preempted,
51462 + MaximumPossibleBW) == FALSE)
51464 + zlog_info ("cannot allocate, BW exhausted %s %d", __FILE__,
51465 + __LINE__);
51466 + return E_ERR;
51469 + if ((pBwOwnerEntry =
51470 + (BW_OWNER_ENTRY *) XMALLOC (MTYPE_TE,
51471 + sizeof (BW_OWNER_ENTRY))) == NULL)
51473 + zlog_err ("\nFailed to allocate memory %s %d", __FILE__, __LINE__);
51474 + return E_ERR;
51476 + pBwOwnerEntry->key = *key;
51477 + pBwOwnerEntry->Node.key_info = (uns8 *) & pBwOwnerEntry->key;
51478 + if (patricia_tree_add
51479 + (&BwOwnersTree[HoldPriority], &pBwOwnerEntry->Node) != E_OK)
51481 + zlog_err ("\nFailed to allocate memory %s %d", __FILE__, __LINE__);
51482 + return E_ERR;
51485 + /* BW reservation does not exist on the particular TE link and If */
51486 + if ((pBwOwnerData =
51487 + (BW_OWNER_DATA *) XMALLOC (MTYPE_TE, sizeof (BW_OWNER_DATA))) == NULL)
51489 + zlog_err ("\nFailed to allocate memory %s %d", __FILE__, __LINE__);
51490 + return E_ERR;
51492 + pBwOwnerData->next = pBwOwnerEntry->pBwOwnerData;
51493 + pBwOwnerEntry->pBwOwnerData = pBwOwnerData;
51494 + pBwOwnerData->BW = BW;
51495 + pBwOwnerData->OutIf = OutIfIndex;
51496 + pBwOwnerData->TeLinkId = TeLinkId;
51498 + if (pComponentLink->ReservableBW[SetupPriority] < BW)
51500 + float TempBW = BW;
51501 + uns32 Prio = 7;
51502 + while (TempBW > 0)
51504 + float FoundBW;
51506 + if ((FoundBW = PreemptTunnel (TeLinkId,
51507 + pComponentLink,
51508 + Prio, HoldPriority, key)) == 0)
51510 + if (Prio == (SetupPriority + 1))
51512 + zlog_err ("Algorithmic error %s %d", __FILE__, __LINE__);
51513 + return E_ERR;
51515 + else
51517 + Prio--;
51520 + TempBW -= FoundBW;
51523 + /* if we're here, allocation succeeded */
51524 + /* cancel BW allocation at other priorities */
51525 + CancelBwAllocAtOtherPriorities (key, TeLinkId, pComponentLink,
51526 + HoldPriority);
51528 + rdb_te_link_max_lsp_bw_calc (pTeLink);
51530 + BwUpdateRequest2Igp (pTeLink);
51532 + /* Update If-BW owners structure */
51533 + if (UpdateIfBwOwnerStructure
51534 + (pComponentLink->oifIndex, key, BW, HoldPriority) != E_OK)
51536 + zlog_err ("cannot update IfBwOwnerStructure %s %d", __FILE__, __LINE__);
51537 + return E_ERR;
51539 + return E_OK;
51542 +uns32
51543 +DoRelease (PSB_KEY * key, uns32 TeLinkId, uns32 OutIfIndex, uns8 Priority)
51545 + BW_OWNER_ENTRY *pBwOwnerEntry;
51546 + BW_OWNER_DATA *pBwOwnerData, *pBwOwnerDataPrev;
51547 + COMPONENT_LINK *pComponentLink = NULL;
51548 + TE_LINK *pTeLink = NULL;
51549 + float Released = 0;
51550 + zlog_info ("inside of DoRelease..");
51551 + if ((pBwOwnerEntry =
51552 + (BW_OWNER_ENTRY *) patricia_tree_get (&BwOwnersTree[Priority],
51553 + (const uns8 *) key)) != NULL)
51555 + pBwOwnerDataPrev = pBwOwnerData = pBwOwnerEntry->pBwOwnerData;
51556 + while (pBwOwnerData != NULL)
51558 + if ((pBwOwnerData->TeLinkId == TeLinkId) &&
51559 + (pBwOwnerData->OutIf == OutIfIndex))
51561 + Released = pBwOwnerData->BW + pBwOwnerData->PreAllocBW;
51562 + zlog_info ("pBwOwnerData->BW %f, PreallocBW %f",
51563 + pBwOwnerData->BW, pBwOwnerData->PreAllocBW);
51564 + if (rdb_get_component_link
51565 + (TeLinkId, OutIfIndex, &pComponentLink) != E_OK)
51567 + zlog_info ("\ncannot get componentl link %x %x %s %x",
51568 + TeLinkId, OutIfIndex, __FILE__, __LINE__);
51569 + return E_ERR;
51572 + if (rdb_get_te_link (TeLinkId, &pTeLink) != E_OK)
51574 + zlog_err ("\ncannot get TE link %s %d", __FILE__, __LINE__);
51576 + ReleaseBW (pTeLink, pComponentLink, Priority, Released);
51577 + rdb_te_link_max_lsp_bw_calc (pTeLink);
51578 + BwUpdateRequest2Igp (pTeLink);
51579 + zlog_info ("BW Owners Entry will be deleted");
51580 + te_stop_timer (&pBwOwnerData->BwHoldTimer);
51581 + if (pBwOwnerEntry->pBwOwnerData == pBwOwnerData)
51582 + pBwOwnerEntry->pBwOwnerData =
51583 + pBwOwnerEntry->pBwOwnerData->next;
51584 + else
51585 + pBwOwnerDataPrev->next = pBwOwnerData->next;
51586 + XFREE (MTYPE_TE, pBwOwnerData);
51587 + if (pBwOwnerEntry->pBwOwnerData == NULL)
51589 + if (patricia_tree_del
51590 + (&BwOwnersTree[Priority], &pBwOwnerEntry->Node) != E_OK)
51592 + zlog_err ("\ncannot delete node from patricia %s %d",
51593 + __FILE__, __LINE__);
51595 + else
51597 + XFREE (MTYPE_TE, pBwOwnerEntry);
51600 + if (UpdateIfBwOwnerStructure
51601 + (pComponentLink->oifIndex, key, Released, Priority) != E_OK)
51603 + zlog_err ("\ncannot update IfBwOwnerStructure %s %d",
51604 + __FILE__, __LINE__);
51605 + return E_ERR;
51607 + return E_OK;
51609 + pBwOwnerDataPrev = pBwOwnerData;
51610 + pBwOwnerData = pBwOwnerData->next;
51613 + else
51615 + zlog_err ("\ncannot get entry from BW owners patricia tree %s %d",
51616 + __FILE__, __LINE__);
51617 + return E_ERR;
51619 + return E_OK;
51622 +static void
51623 +AllocateBW (TE_LINK * pTeLink, COMPONENT_LINK * pComponentLink, uns8 Priority,
51624 + float BW)
51626 + int j;
51628 + if (pComponentLink->ReservableBW[Priority] >= BW)
51630 + pComponentLink->ReservableBW[Priority] -= BW;
51631 + pTeLink->te_link_properties.ReservableBW[Priority] -= BW;
51632 + pComponentLink->AllocatedBW[Priority][Priority] += BW;
51634 + else
51636 + pComponentLink->ReservableBW[Priority] = 0;
51639 + for (j = Priority + 1; j < 8; j++)
51641 + if (pComponentLink->ReservableBW[j] >= BW)
51643 + pComponentLink->ReservableBW[j] -= BW;
51644 + pTeLink->te_link_properties.ReservableBW[j] -= BW;
51646 + else
51648 + pComponentLink->ReservableBW[j] = 0;
51653 +static void
51654 +ReleaseBW (TE_LINK * pTeLink, COMPONENT_LINK * pComponentLink, uns8 Priority,
51655 + float BW)
51657 + int i, j;
51658 + float ReleasedBW = 0;
51659 + /* Find highest priority where BW remains to be allocated */
51660 + for (i = 0; (i < 8) && (BW > 0); i++)
51662 + if (pComponentLink->AllocatedBW[i][i] > 0)
51664 + ReleasedBW = 0;
51665 + if (BW >= pComponentLink->AllocatedBW[i][i])
51667 + ReleasedBW = pComponentLink->AllocatedBW[i][i];
51668 + pComponentLink->ReservableBW[i] +=
51669 + pComponentLink->AllocatedBW[i][i];
51670 + pTeLink->te_link_properties.ReservableBW[i] +=
51671 + pComponentLink->AllocatedBW[i][i];
51672 + BW -= pComponentLink->AllocatedBW[i][i];
51673 + pComponentLink->AllocatedBW[i][i] = 0;
51675 + else
51677 + ReleasedBW = BW;
51678 + pComponentLink->ReservableBW[i] += BW;
51679 + pTeLink->te_link_properties.ReservableBW[i] += BW;
51680 + pComponentLink->AllocatedBW[i][i] -= BW;
51681 + BW = 0;
51683 + for (j = i + 1; (j < 8) && (ReleasedBW > 0); j++)
51685 + if (pComponentLink->AllocatedBW[i][j] > 0)
51687 + if (ReleasedBW >= pComponentLink->AllocatedBW[i][j])
51689 + pComponentLink->AllocatedBW[j][j] +=
51690 + pComponentLink->AllocatedBW[i][j];
51691 + ReleasedBW -= pComponentLink->AllocatedBW[i][j];
51692 + pComponentLink->AllocatedBW[i][j] = 0;
51694 + else
51696 + pComponentLink->AllocatedBW[j][j] += ReleasedBW;
51697 + pComponentLink->AllocatedBW[i][j] -= ReleasedBW;
51698 + ReleasedBW = 0;
51704 + if (ReleasedBW > 0)
51706 + for (; i < 8; i++)
51708 + if (pComponentLink->AllocatedBW[i][i] > 0)
51710 + break;
51712 + if (pComponentLink->ConfiguredReservableBW[i] >
51713 + pComponentLink->ReservableBW[i])
51715 + if ((pComponentLink->ReservableBW[i] + ReleasedBW) <=
51716 + pComponentLink->ConfiguredReservableBW[i])
51718 + pComponentLink->ReservableBW[i] += ReleasedBW;
51719 + pTeLink->te_link_properties.ReservableBW[i] += ReleasedBW;
51721 + else
51723 + pTeLink->te_link_properties.ReservableBW[i] =
51724 + (pComponentLink->ConfiguredReservableBW[i] -
51725 + pComponentLink->ReservableBW[i]);
51726 + pComponentLink->ReservableBW[i] =
51727 + pComponentLink->ConfiguredReservableBW[i];
51734 +static void
51735 +PreemptBW (COMPONENT_LINK * pComponentLink,
51736 + uns8 PreemptorPriority, uns8 PreemptedPriority, float BW)
51738 + int i;
51739 + if (PreemptedPriority == 0)
51741 + zlog_err ("\nBUG: Preempted priority is 0!!!");
51742 + return;
51744 + for (i = 7; (i >= PreemptedPriority) && (BW > 0); i--)
51746 + if (pComponentLink->AllocatedBW[PreemptedPriority][i] > 0)
51748 + if (pComponentLink->AllocatedBW[PreemptedPriority][i] >= BW)
51750 + pComponentLink->AllocatedBW[PreemptedPriority][i] -= BW;
51751 + pComponentLink->AllocatedBW[PreemptorPriority][i] += BW;
51752 + return;
51754 + else
51756 + pComponentLink->AllocatedBW[PreemptorPriority][i] +=
51757 + pComponentLink->AllocatedBW[PreemptedPriority][i];
51758 + BW -= pComponentLink->AllocatedBW[PreemptedPriority][i];
51759 + pComponentLink->AllocatedBW[PreemptedPriority][i] = 0;
51763 + if (BW > 0)
51765 + zlog_err ("\nBUG: BW > 0 %s %d", __FILE__, __LINE__);
51769 +void
51770 +BwOwnersDump ()
51772 + BW_OWNER_ENTRY *pBwOwnerEntry;
51773 + BW_OWNER_DATA *pBwOwnerData;
51774 + PSB_KEY PsbKey;
51775 + int j;
51777 + for (j = 0; j < 8; j++)
51779 + memset (&PsbKey, 0, sizeof (PSB_KEY));
51780 + zlog_debug ("Priority# %x", j);
51781 + while ((pBwOwnerEntry =
51782 + (BW_OWNER_ENTRY *) patricia_tree_getnext (&BwOwnersTree[j],
51783 + (const uns8 *)
51784 + &PsbKey)) != NULL)
51786 + zlog_debug
51787 + ("owner dest %x tunnel id %x ext tunnel id %x sender ip %x lsp id %x",
51788 + pBwOwnerEntry->key.Session.Dest,
51789 + pBwOwnerEntry->key.Session.TunnelId,
51790 + pBwOwnerEntry->key.Session.ExtTunelId,
51791 + pBwOwnerEntry->key.SenderTemplate.IpAddr,
51792 + pBwOwnerEntry->key.SenderTemplate.LspId);
51793 + pBwOwnerData = pBwOwnerEntry->pBwOwnerData;
51794 + while (pBwOwnerData != NULL)
51796 + zlog_debug ("TE Link ID %x Out IF %x BW %f PreAlloc BW %f",
51797 + pBwOwnerData->BW,
51798 + pBwOwnerData->TeLinkId,
51799 + pBwOwnerData->OutIf, pBwOwnerData->PreAllocBW);
51800 + pBwOwnerData = pBwOwnerData->next;
51802 + PsbKey = pBwOwnerEntry->key;
51805 + return;
51808 +void
51809 +IfBwOwnersDump ()
51811 + IF_BW_KEY if_bw_key;
51812 + IF_BW_DATA *pIfBwEntry;
51813 + int j;
51815 + memset (&if_bw_key, 0, sizeof (IF_BW_KEY));
51817 + for (j = 0; j < 8; j++)
51819 + zlog_debug ("Priority#%x", j);
51820 + while ((pIfBwEntry =
51821 + (IF_BW_DATA *) patricia_tree_getnext (&IfBwOwnersTree[j],
51822 + (const uns8 *)
51823 + &if_bw_key)) != NULL)
51825 + zlog_debug ("IF#%x Dest #%x Tunnel #%x Source #%x BW #%f",
51826 + pIfBwEntry->if_bw_key.IfIndex,
51827 + pIfBwEntry->if_bw_key.PsbKey.Session.Dest,
51828 + pIfBwEntry->if_bw_key.PsbKey.Session.TunnelId,
51829 + pIfBwEntry->if_bw_key.PsbKey.Session.ExtTunelId,
51830 + pIfBwEntry->BW);
51831 + if_bw_key = pIfBwEntry->if_bw_key;
51834 + return;
51836 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_bw_man.h quagga-mpls/rsvpd/te_bw_man.h
51837 --- quagga/rsvpd/te_bw_man.h 1969-12-31 18:00:00.000000000 -0600
51838 +++ quagga-mpls/rsvpd/te_bw_man.h 2007-06-18 23:55:58.000000000 -0500
51839 @@ -0,0 +1,30 @@
51841 +#ifndef _BW_MAN_H_
51842 +#define _BW_MAN_H_
51844 +uns32 DoPreBwAllocation (PSB_KEY * key,
51845 + uns32 TeLinkId,
51846 + COMPONENT_LINK * pComponentLink,
51847 + float BW, uns8 HoldPriority);
51848 +uns32 CalcActualAlloc (PSB_KEY * key,
51849 + uns32 TeLinkId,
51850 + COMPONENT_LINK * pComponentLink,
51851 + float *BW,
51852 + uns8 SetupPriority,
51853 + uns8 HoldPriority, uns8 * PreemptedPriority);
51854 +uns32 TE_RSVPTE_API_DoAllocation (PSB_KEY * key,
51855 + uns32 TeLinkId,
51856 + uns32 OutIfIndex,
51857 + float BW,
51858 + uns8 SetupPriority,
51859 + uns8 HoldPriority,
51860 + float *MaximumPossibleBW);
51861 +uns32 DoRelease (PSB_KEY * key, uns32 TeLinkId, uns32 OutIfIndex,
51862 + uns8 Priority);
51863 +void BwOwnersDump ();
51864 +void IfBwOwnersDump ();
51866 +void TE_RSVPTE_API_BwReleaseMessage (TE_API_MSG * dmsg);
51867 +void BwUpdateRequest2Igp (TE_LINK * pTeLink);
51869 +#endif
51870 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_common.c quagga-mpls/rsvpd/te_common.c
51871 --- quagga/rsvpd/te_common.c 1969-12-31 18:00:00.000000000 -0600
51872 +++ quagga-mpls/rsvpd/te_common.c 2007-06-19 00:13:49.000000000 -0500
51873 @@ -0,0 +1,1685 @@
51874 +/* Module: te_common_proc.c
51875 + Contains: TE application common procedures
51876 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
51877 + */
51878 +#include "te.h"
51879 +#include "thread.h"
51880 +#include "vty.h"
51882 +extern struct thread_master *master;
51884 +PATRICIA_TREE PlatformWideFreeLabels;
51885 +PATRICIA_TREE BwOwnersTree[8];
51886 +PATRICIA_TREE IfBwOwnersTree[8];
51887 +PATRICIA_TREE SeparateAdaptiveLspsTrunkTree;
51888 +PATRICIA_TREE SeparateNonAdaptiveLspsTrunkTree;
51889 +PATRICIA_TREE NonSeparateServiceLspsTrunkTree;
51890 +PATRICIA_TREE NonSeparateServiceBWAdaptiveLspsTrunkTree;
51891 +PATRICIA_TREE NonSeparateTunnelsLspsTrunkTree;
51892 +PATRICIA_TREE SLAsTree;
51893 +PATRICIA_TREE ConstraintRouteResReqTree;
51894 +PATRICIA_TREE ConstraintRouteResClientsTree;
51896 +USER_LSP_LIST *UserLspListHead;
51898 +#define MAX_TUNNELS_IF 1000
51899 +#define TUNNELS_IF_OFFSET 100
51901 +IPV4_ADDR tunnels_if_array[MAX_TUNNELS_IF];
51902 +extern LABEL_ENTRY PlatformWideLabelSpace[LABEL_SPACE_SIZE];
51904 +SM_CALL_T *(*sm_handler[MAX_SM]) (SM_T * pSm, SM_EVENT_T * sm_data) =
51906 + lsp_sm_handler,
51907 + transit_req_sm_handler, constraint_route_resolution_sm_handler
51908 +#ifdef FRR_SM_DEFINED
51909 + , fast_reroute_sm_handler
51910 +#endif
51913 +void
51914 +sm_gen_event_trace (SM_E event)
51916 + switch (event)
51918 + case USER_LSP_REQUEST_EVENT:
51919 + zlog_info ("USER_LSP_REQUEST_EVENT\n");
51920 + break;
51921 + case SLA_USER_REQUEST_EVENT:
51922 + zlog_info ("SLA_USER_REQUEST_EVENT\n");
51923 + break;
51924 + case INGRESS_LSP_REQUEST_EVENT:
51925 + zlog_info ("INGRESS_LSP_REQUEST_EVENT\n");
51926 + break;
51927 + case SLA_DELETE_USER_REQUEST_EVENT:
51928 + zlog_info ("SLA_DELETE_USER_REQUEST_EVENT\n");
51929 + break;
51930 + case INGRESS_LSP_DELETE_REQUEST_EVENT:
51931 + zlog_info ("INGRESS_LSP_DELETE_REQUEST_EVENT\n");
51932 + break;
51933 + case TRANSIT_REQ_EVENT:
51934 + zlog_info ("TRANSIT_REQ_EVENT\n");
51935 + break;
51936 + case CONSTRAINT_ROUTE_RESOLUTION_REQ_EVENT:
51937 + zlog_info ("CONSTRAINT_ROUTE_RESOLUTION_REQ_EVENT\n");
51938 + break;
51939 + case CONSTRAINT_ROUTE_RESOLVED_EVENT:
51940 + zlog_info ("CONSTRAINT_ROUTE_RESOLVED_EVENT\n");
51941 + break;
51942 + case CONSTRAINT_ROUTE_RESOLVE_FAILED_EVENT:
51943 + zlog_info ("CONSTRAINT_ROUTE_RESOLVE_FAILED_EVENT\n");
51944 + break;
51945 + case CSPF_REPLY_EVENT:
51946 + zlog_info ("CSPF_REPLY_EVENT\n");
51947 + break;
51948 + case DYNAMIC_ADAPTATION_REQ_EVENT:
51949 + zlog_info ("DYNAMIC_ADAPTATION_REQ_EVENT\n");
51950 + break;
51951 + case SLA_ADAPTATION_REQ_EVENT:
51952 + zlog_info ("SLA_ADAPTATION_REQ_EVENT\n");
51953 + break;
51954 + case SLA_ADAPTATION_COMPLETE_EVENT:
51955 + zlog_info ("SLA_ADAPTATION_COMPLETE_EVENT\n");
51956 + break;
51957 + case SLA_ADAPTATION_FAILED_EVENT:
51958 + zlog_info ("SLA ADAPTATION FAILED EVENT\n");
51959 + break;
51960 + case INGRESS_LSP_OPERATION_COMPLETE_EVENT:
51961 + zlog_info ("INGRESS_LSP_OPERATION_COMPLETE_EVENT\n");
51962 + break;
51963 + case INGRESS_LSP_OPERATION_FAILED_EVENT:
51964 + zlog_info ("INGRESS_LSP_OPERATION_FAILED_EVENT\n");
51965 + break;
51966 + case MPLS_SIGNALING_INGRESS_ESTABLISHED_NOTIFICATION_EVENT:
51967 + zlog_info ("MPLS_SIGNALING_INGRESS_ESTABLISHED_NOTIFICATION_EVENT\n");
51968 + break;
51969 + case MPLS_SIGNALING_INGRESS_FAILED_NOTIFICATION_EVENT:
51970 + zlog_info ("MPLS_SIGNALING_INGRESS_FAILED_NOTIFICATION_EVENT\n");
51971 + break;
51972 + case LSP_SETUP_TIMER_EXPIRY:
51973 + zlog_info ("LSP_SETUP_TIMER_EXPIRY\n");
51974 + break;
51975 + case ADAPTIVITY_TIMER_EXPIRY:
51976 + zlog_info ("ADAPTIVITY_TIMER_EXPIRY\n");
51977 + break;
51978 + case RETRY_TIMER_EXPIRY:
51979 + zlog_info ("RETRY_TIMER_EXPIRY\n");
51980 + break;
51981 + case CSPF_RETRY_EVENT:
51982 + zlog_info ("CSPF_RETRY_EVENT\n");
51983 + break;
51984 + default:
51985 + zlog_err ("\nunknown event %d", event);
51990 +int
51991 +sm_gen_async_event_send (SM_T * sm, SM_EVENT_E event, void *data)
51993 + TE_MSG dmsg;
51994 + SM_CALL_T *sm_packet;
51995 + SM_EVENT_T *pEvent = (SM_EVENT_T *) XMALLOC (MTYPE_TE, sizeof (SM_EVENT_T));
51996 + if (pEvent == NULL)
51998 + zlog_err ("\nmalloc failed %s %d %d", __FILE__, __LINE__, event);
51999 + return 1;
52001 + dmsg.event = EVENT_TE_SM;
52002 + pEvent->event = event;
52003 + pEvent->data = data;
52004 + sm_packet = (SM_CALL_T *) XMALLOC (MTYPE_TE, sizeof (SM_CALL_T));
52005 + if (sm_packet == NULL)
52007 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
52008 + XFREE (MTYPE_TE, pEvent);
52009 + return 1;
52011 + sm_packet->sm = sm;
52012 + sm_packet->sm_data = pEvent;
52013 + dmsg.u.te_sm_event.data = sm_packet;
52014 + te_send_msg (&dmsg, sizeof (TE_MSG));
52015 + return 0;
52018 +SM_CALL_T *
52019 +sm_gen_sync_event_send (SM_T * sm, SM_EVENT_E event, void *data)
52021 + SM_CALL_T *sm_packet;
52022 + SM_EVENT_T *pEvent = (SM_EVENT_T *) XMALLOC (MTYPE_TE, sizeof (SM_EVENT_T));
52023 + if (pEvent == NULL)
52025 + zlog_err ("\nmalloc failed %s %d %d", __FILE__, __LINE__, event);
52026 + return NULL;
52028 + pEvent->event = event;
52029 + pEvent->data = data;
52030 + sm_packet = (SM_CALL_T *) XMALLOC (MTYPE_TE, sizeof (SM_CALL_T));
52031 + if (sm_packet == NULL)
52033 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
52034 + XFREE (MTYPE_TE, pEvent);
52035 + return NULL;
52037 + sm_packet->sm = sm;
52038 + sm_packet->sm_data = pEvent;
52039 + return sm_packet;
52042 +void
52043 +sm_call (SM_CALL_T * sm_packet)
52045 + SM_CALL_T *pPacket = sm_packet, *pPrevPacket;
52046 + SM_E sm_type;
52048 + do
52050 + sm_type = pPacket->sm->sm_type;
52051 + pPrevPacket = pPacket;
52052 + pPacket = sm_handler[sm_type] (pPacket->sm, pPacket->sm_data);
52053 + XFREE (MTYPE_TE, pPrevPacket->sm_data);
52054 + XFREE (MTYPE_TE, pPrevPacket);
52056 + while (pPacket != NULL);
52059 +SM_T *
52060 +sm_gen_alloc (SM_T * caller, SM_E sm_type)
52062 + SM_T *pSmGen;
52063 + pSmGen = (SM_T *) XMALLOC (MTYPE_TE, sizeof (SM_T));
52064 + if (pSmGen == NULL)
52066 + zlog_err ("\ncannot allocate memory %s %d", __FILE__, __LINE__);
52067 + return NULL;
52069 + pSmGen->data = NULL;
52070 + pSmGen->sm_type = sm_type;
52071 + pSmGen->caller = caller;
52072 + pSmGen->state = INIT_STATE;
52073 + return pSmGen;
52076 +void
52077 +sm_gen_free (SM_T * sm)
52079 + XFREE (MTYPE_TE, sm);
52080 + return;
52083 +#if 1
52085 +//extern PATRICIA_TREE BwOwnersTree[8];
52087 +void
52088 +BwHoldTimerExpiry (BW_HOLD_TIMER_DATA * pBwHoldTimerExpiry)
52090 + BW_OWNER_ENTRY *pBwOwnerEntry;
52091 + BW_OWNER_DATA *pBwOwnerData;
52092 + COMPONENT_LINK *pComponentLink = NULL;
52093 + TE_LINK *pTeLink = NULL;
52094 + int j;
52095 + uns8 Priority = pBwHoldTimerExpiry->Priority;
52097 + if ((pBwOwnerEntry =
52098 + (BW_OWNER_ENTRY *) patricia_tree_get (&BwOwnersTree[Priority],
52099 + (const uns8 *)
52100 + &pBwHoldTimerExpiry->key)) !=
52101 + NULL)
52103 + pBwOwnerData = pBwOwnerEntry->pBwOwnerData;
52104 + while (pBwOwnerData != NULL)
52106 + if ((pBwOwnerData->TeLinkId == pBwHoldTimerExpiry->TeLinkId) &&
52107 + (pBwOwnerData->OutIf == pBwHoldTimerExpiry->OutIf))
52109 + if (pBwOwnerData !=
52110 + (BW_OWNER_DATA *) pBwHoldTimerExpiry->handle)
52112 + zlog_err ("unexpected timer expiry %s %d", __FILE__,
52113 + __LINE__);
52114 + pBwOwnerData->PreAllocBW = 0;
52115 + pBwOwnerData->BwHoldTimer.data.bw_hold_data.BW = 0;
52116 + pBwOwnerData->BwHoldTimer.is_active = FALSE;
52117 + return;
52119 + if (pBwOwnerData->PreAllocBW !=
52120 + pBwOwnerData->BwHoldTimer.data.bw_hold_data.BW)
52122 + zlog_err ("unexpected timer expiry %s %d", __FILE__,
52123 + __LINE__);
52124 + pBwOwnerData->PreAllocBW = 0;
52125 + pBwOwnerData->BwHoldTimer.data.bw_hold_data.BW = 0;
52126 + pBwOwnerData->BwHoldTimer.is_active = FALSE;
52127 + return;
52129 + if (rdb_get_component_link (pBwHoldTimerExpiry->TeLinkId,
52130 + pBwHoldTimerExpiry->OutIf,
52131 + &pComponentLink) != E_OK)
52133 + zlog_err ("cannot get component link %s %d", __FILE__,
52134 + __LINE__);
52135 + pBwOwnerData->PreAllocBW = 0;
52136 + pBwOwnerData->BwHoldTimer.data.bw_hold_data.BW = 0;
52137 + pBwOwnerData->BwHoldTimer.is_active = FALSE;
52138 + return;
52140 + zlog_info
52141 + ("releasing BW: DestIP %x Source %x tunnel %x TmrBW %f EntryBW %f Priority %x",
52142 + pBwHoldTimerExpiry->key.Session.Dest,
52143 + pBwHoldTimerExpiry->key.Session.ExtTunelId,
52144 + pBwHoldTimerExpiry->key.Session.TunnelId,
52145 + pBwHoldTimerExpiry->BW, pBwOwnerData->BW,
52146 + pBwHoldTimerExpiry->Priority);
52147 + if (rdb_get_te_link (pBwHoldTimerExpiry->TeLinkId, &pTeLink) !=
52148 + E_OK)
52150 + zlog_err ("\ncannot get TE link %s %d", __FILE__, __LINE__);
52152 + for (j = Priority; j < 8; j++)
52154 + pComponentLink->ReservableBW[j] += pBwOwnerData->PreAllocBW;
52155 + pTeLink->te_link_properties.ReservableBW[j] +=
52156 + pBwOwnerData->PreAllocBW;
52158 + rdb_te_link_max_lsp_bw_calc (pTeLink);
52159 + pBwOwnerData->PreAllocBW = 0;
52160 + pBwOwnerData->BwHoldTimer.is_active = FALSE;
52161 + pBwOwnerData->BwHoldTimer.data.bw_hold_data.BW = 0;
52162 + return;
52164 + pBwOwnerData = pBwOwnerData->next;
52166 + zlog_info ("\nBW owner data is not found %s %d", __FILE__, __LINE__);
52168 + else
52170 + zlog_err
52171 + ("\ncannot get entry for BW holder %s %d destIP %x Tunnel ID %x SourceIP %x %x %x Priority %x",
52172 + __FILE__, __LINE__, pBwHoldTimerExpiry->key.Session.Dest,
52173 + pBwHoldTimerExpiry->key.Session.TunnelId,
52174 + pBwHoldTimerExpiry->key.Session.ExtTunelId,
52175 + pBwHoldTimerExpiry->key.SenderTemplate.IpAddr,
52176 + pBwHoldTimerExpiry->key.SenderTemplate.LspId,
52177 + pBwHoldTimerExpiry->Priority);
52181 +void
52182 +LspSetupTimerExpiry (LSP_SETUP_TIMER_DATA * pData)
52184 + RSVP_TUNNEL_PROPERTIES *pTunnel;
52185 + SM_CALL_T *pCall = NULL;
52186 + if (FindTunnel (&pData->key, &pTunnel, ALL_TRUNKS) != TRUE)
52188 + zlog_err ("\ncannot find tunnel %x %x %x",
52189 + pData->key.Session.Dest,
52190 + pData->key.Session.ExtTunelId, pData->key.Session.TunnelId);
52191 + return;
52193 + if (pTunnel->sm_handle == 0)
52195 + zlog_err
52196 + ("\nThere is no SM to process LSP SETUP RETRY for tunnle %x %x %x",
52197 + pData->key.Session.Dest, pData->key.Session.ExtTunelId,
52198 + pData->key.Session.TunnelId);
52199 + return;
52201 + if ((pCall =
52202 + sm_gen_sync_event_send (pTunnel->sm_handle, LSP_SETUP_TIMER_EXPIRY,
52203 + &pData->key)) == NULL)
52205 + zlog_err ("\ncannot send sync event %s %d", __FILE__, __LINE__);
52206 + return;
52208 + sm_call (pCall);
52211 +void
52212 +AdaptivityTimerExpiry (ADAPTIVITY_TIMER_DATA * pData)
52214 + RSVP_TUNNEL_PROPERTIES *pTunnel;
52215 + SM_CALL_T *pCall = NULL;
52216 + if (FindTunnel (&pData->key, &pTunnel, ALL_TRUNKS) != TRUE)
52218 + zlog_err ("\ncannot find tunnel %x %x %x",
52219 + pData->key.Session.Dest,
52220 + pData->key.Session.ExtTunelId, pData->key.Session.TunnelId);
52221 + return;
52223 + if (pTunnel->sm_handle == 0)
52225 + zlog_err
52226 + ("\nThere is no SM to process LSP SETUP RETRY for tunnle %x %x %x",
52227 + pData->key.Session.Dest, pData->key.Session.ExtTunelId,
52228 + pData->key.Session.TunnelId);
52229 + return;
52231 + if ((pCall =
52232 + sm_gen_sync_event_send (pTunnel->sm_handle, ADAPTIVITY_TIMER_EXPIRY,
52233 + &pData->key)) == NULL)
52235 + zlog_err ("\ncannot send sync event %s %d", __FILE__, __LINE__);
52236 + return;
52238 + sm_call (pCall);
52241 +void
52242 +LspSetupRetryTimerExpiry (LSP_SETUP_RETRY_TIMER_DATA * pData)
52244 + RSVP_TUNNEL_PROPERTIES *pTunnel;
52245 + SM_CALL_T *pCall = NULL;
52246 + if (FindTunnel (&pData->key, &pTunnel, ALL_TRUNKS) != TRUE)
52248 + zlog_err ("\ncannot find tunnel %x %x %x",
52249 + pData->key.Session.Dest,
52250 + pData->key.Session.ExtTunelId, pData->key.Session.TunnelId);
52251 + return;
52253 + if (pTunnel->sm_handle == 0)
52255 + zlog_err
52256 + ("\nThere is no SM to process LSP SETUP RETRY for tunnlel %x %x %x",
52257 + pData->key.Session.Dest, pData->key.Session.ExtTunelId,
52258 + pData->key.Session.TunnelId);
52259 + return;
52261 + if ((pCall =
52262 + sm_gen_sync_event_send (pTunnel->sm_handle, RETRY_TIMER_EXPIRY,
52263 + &pData->key)) == NULL)
52265 + zlog_err ("\ncannot send sync event %s %d", __FILE__, __LINE__);
52266 + return;
52268 + sm_call (pCall);
52271 +void
52272 +CspfRetryTimerExpiry (CSPF_RETRY_TIMER_DATA * pData)
52274 + RSVP_TUNNEL_PROPERTIES *pTunnel;
52275 + SM_CALL_T *pCall = NULL;
52276 + if (FindTunnel (&pData->key, &pTunnel, ALL_TRUNKS) != TRUE)
52278 + zlog_err ("\ncannot find tunnel %x %x %x",
52279 + pData->key.Session.Dest,
52280 + pData->key.Session.ExtTunelId, pData->key.Session.TunnelId);
52281 + return;
52283 + if (pTunnel->sm_handle == 0)
52285 + zlog_err ("There is no SM to process CSPF RETRY for tunnlel %x %x %x",
52286 + pData->key.Session.Dest,
52287 + pData->key.Session.ExtTunelId, pData->key.Session.TunnelId);
52288 + return;
52290 + if ((pCall =
52291 + sm_gen_sync_event_send (pTunnel->sm_handle, CSPF_RETRY_EVENT,
52292 + &pData->key)) == NULL)
52294 + zlog_err ("\ncannot send sync event %s %d", __FILE__, __LINE__);
52295 + return;
52297 + sm_call (pCall);
52300 +void
52301 +te_timer_expiry (struct thread *thread)
52303 + TE_TMR *tmr = (TE_TMR *) THREAD_ARG (thread);
52304 + int period = THREAD_VAL (tmr->thread);
52305 + tmr->thread = thread_add_timer (master, te_timer_expiry, tmr, period);
52307 + tmr->is_active = FALSE;
52309 + switch (tmr->type)
52311 + case BW_HOLD_EXPIRY:
52312 + zlog_info
52313 + ("BW Hold expiry: TE Link ID %x IP Dest %x Tunnel ID %x Source %x BW %f Priority %x",
52314 + tmr->data.bw_hold_data.TeLinkId,
52315 + tmr->data.bw_hold_data.key.Session.Dest,
52316 + tmr->data.bw_hold_data.key.Session.TunnelId,
52317 + tmr->data.bw_hold_data.key.Session.ExtTunelId,
52318 + tmr->data.bw_hold_data.BW, tmr->data.bw_hold_data.Priority);
52319 + BwHoldTimerExpiry (&tmr->data.bw_hold_data);
52320 + break;
52321 + case LSP_SETUP_EXPIRY:
52322 + zlog_info ("LSP SETUP expiry: %x %x %x",
52323 + tmr->data.lsp_setup_data.key.Session.Dest,
52324 + tmr->data.lsp_setup_data.key.Session.TunnelId,
52325 + tmr->data.lsp_setup_data.key.Session.ExtTunelId);
52326 + LspSetupTimerExpiry (&tmr->data.lsp_setup_data);
52327 + break;
52328 + case ADAPTIVITY_EXPIRY:
52329 + AdaptivityTimerExpiry (&tmr->data.adaptivity_timer_data);
52330 + break;
52331 + case LSP_SETUP_RETRY_EXPIRY:
52332 + zlog_info ("LSP SETUP RETRY expiry: %x %x %x",
52333 + tmr->data.lsp_setup_retry_data.key.Session.Dest,
52334 + tmr->data.lsp_setup_retry_data.key.Session.TunnelId,
52335 + tmr->data.lsp_setup_retry_data.key.Session.ExtTunelId);
52336 + LspSetupRetryTimerExpiry (&tmr->data.lsp_setup_retry_data);
52337 + break;
52338 + case CSPF_RETRY_EXPIRY:
52339 + zlog_info ("CSPF RETRY expiry: %x %x %x",
52340 + tmr->data.cspf_retry_data.key.Session.Dest,
52341 + tmr->data.cspf_retry_data.key.Session.TunnelId,
52342 + tmr->data.cspf_retry_data.key.Session.ExtTunelId);
52343 + CspfRetryTimerExpiry (&tmr->data.cspf_retry_data);
52344 + break;
52345 +#if 0
52346 + case BYPASS_TUNNEL_RETRY_EXPIRY:
52347 + dmsg.event = EVENT_BYPASS_TUNNEL_RETRY_EXPIRY;
52348 + memcpy (&dmsg.u.bypass_retry_expiry.key,
52349 + &tmr->data.bypass_retry_data, sizeof (FRR_SM_KEY));
52350 + zlog_info ("\nBYPASS TUNNEL RETRY expiry: %x %x %x",
52351 + tmr->data.bypass_retry_data.merge_node,
52352 + tmr->data.bypass_retry_data.OutIfIndex,
52353 + tmr->data.bypass_retry_data.protected_node);
52354 + te_send_msg (&dmsg, sizeof (TE_MSG));
52355 + break;
52356 +#endif
52357 + default:
52358 + zlog_err ("\ndefault case %s %d", __FILE__, __LINE__);
52360 + return;
52363 +uns32
52364 +te_start_timer (TE_TMR * tmr, TE_TMR_E type, uns32 period)
52366 + zlog_info ("entering te_start_timer");
52367 + if (tmr->thread)
52369 + te_stop_timer (tmr);
52371 + tmr->type = type;
52372 + if (tmr->is_active == FALSE)
52374 + tmr->thread = thread_add_timer (master, te_timer_expiry, tmr, period);
52375 + THREAD_VAL (tmr->thread) = period;
52376 + tmr->is_active = TRUE;
52378 + zlog_info ("leaving te_start_timer");
52379 + return E_OK;
52382 +void
52383 +te_stop_timer (TE_TMR * tmr)
52385 + /* Stop the timer if it is active... */
52386 + zlog_info ("entering te_stop_timer");
52387 + if (tmr->is_active == TRUE)
52389 + thread_cancel (tmr->thread);
52390 + tmr->thread = NULL;
52391 + tmr->is_active = FALSE;
52393 + zlog_info ("leaving te_stop_timer");
52395 +#endif
52397 +uns32
52398 +TeApplicationInit ()
52400 + PATRICIA_PARAMS params;
52401 + unsigned int i;
52403 + UserLspListHead = NULL;
52405 + params.key_size = sizeof (unsigned int);
52406 + params.info_size = 0;
52407 + memset (PlatformWideLabelSpace, 0, sizeof (LABEL_ENTRY) * LABEL_SPACE_SIZE);
52408 + if (patricia_tree_init (&PlatformWideFreeLabels, &params) != E_OK)
52410 + return E_ERR;
52412 + zlog_info ("\nPlatformWideFreeLabelsTree init succeeded");
52414 + for (i = 0; i < LABEL_SPACE_SIZE; i++)
52416 + PlatformWideLabelSpace[i].label = i + 1;
52417 + PlatformWideLabelSpace[i].ReceivedOutLabel = 0;
52418 + PlatformWideLabelSpace[i].Node.key_info =
52419 + (uns8 *) & PlatformWideLabelSpace[i].label;
52420 + if (patricia_tree_add
52421 + (&PlatformWideFreeLabels,
52422 + &(PlatformWideLabelSpace[i].Node)) != E_OK)
52424 + zlog_err ("\ncannot add label %d", i + 1);
52425 + return E_ERR;
52428 + params.key_size = sizeof (PSB_KEY);
52429 + params.info_size = 0;
52431 + for (i = 0; i < 8; i++)
52433 + if (patricia_tree_init (&BwOwnersTree[i], &params) != E_OK)
52435 + return E_ERR;
52439 + params.key_size = sizeof (PSB_KEY) + sizeof (uns32);
52440 + params.info_size = 0;
52442 + for (i = 0; i < 8; i++)
52444 + if (patricia_tree_init (&IfBwOwnersTree[i], &params) != E_OK)
52446 + return E_ERR;
52450 + memset (&params, 0, sizeof (params));
52451 + params.key_size = sizeof (TRUNK_KEY);
52452 + params.info_size = 0;
52454 + if (patricia_tree_init (&SeparateNonAdaptiveLspsTrunkTree, &params) != E_OK)
52456 + return E_ERR;
52459 + if (patricia_tree_init (&SeparateAdaptiveLspsTrunkTree, &params) != E_OK)
52461 + return E_ERR;
52464 + if (patricia_tree_init (&NonSeparateServiceLspsTrunkTree, &params) != E_OK)
52466 + return E_ERR;
52469 + if (patricia_tree_init (&NonSeparateTunnelsLspsTrunkTree, &params) != E_OK)
52471 + return E_ERR;
52474 + if (patricia_tree_init (&NonSeparateServiceBWAdaptiveLspsTrunkTree,
52475 + &params) != E_OK)
52477 + return E_ERR;
52480 + memset (&params, 0, sizeof (params));
52481 + params.key_size = sizeof (SLA_KEY);
52482 + params.info_size = 0;
52483 + if (patricia_tree_init (&SLAsTree, &params) != E_OK)
52485 + return E_ERR;
52488 + params.key_size = sizeof (IPV4_ADDR);
52489 + params.info_size = 0;
52491 + if (patricia_tree_init (&ConstraintRouteResReqTree, &params) != E_OK)
52493 + return E_ERR;
52496 + params.key_size = sizeof (int);
52497 + params.info_size = 0;
52499 + if (patricia_tree_init (&ConstraintRouteResClientsTree, &params) != E_OK)
52501 + return E_ERR;
52503 +#ifdef FRR_SM_DEFINED
52504 + InitFastReRoute ();
52505 +#endif
52506 + zlog_info ("\nTE application init success");
52507 + return E_OK;
52510 +PATRICIA_TREE *
52511 +GetPatriciaTree (TRUNK_TYPE trunk_type)
52513 + PATRICIA_TREE *pTree = NULL;
52514 + switch (trunk_type)
52516 + case SEPARATE_NON_ADAPTIVE:
52517 + pTree = &SeparateNonAdaptiveLspsTrunkTree;
52518 + break;
52519 + case SEPARATE_ADAPTIVE:
52520 + pTree = &SeparateAdaptiveLspsTrunkTree;
52521 + break;
52522 + case NON_SEPARATE_SERVICE:
52523 + pTree = &NonSeparateServiceLspsTrunkTree;
52524 + break;
52525 + case NON_SEPARATE_SERVICE_BW_ADAPTIVE:
52526 + pTree = &NonSeparateServiceBWAdaptiveLspsTrunkTree;
52527 + break;
52528 + case NON_SEPARATE_TUNNELS:
52529 + pTree = &NonSeparateTunnelsLspsTrunkTree;
52530 + break;
52531 + default:
52532 + zlog_err ("\ndefault case %s %d", __FILE__, __LINE__);
52534 + return pTree;
52537 +BOOL
52538 +FindTunnel (PSB_KEY * PsbKey, RSVP_TUNNEL_PROPERTIES ** ppTunnel,
52539 + TRUNK_TYPE trunk_type)
52541 + TRUNK_KEY trunk_key;
52542 + TRUNK_ENTRY *pTrunkEntry;
52543 + int i, l;
52544 + PATRICIA_TREE *pTree = NULL;
52546 + switch (trunk_type)
52548 + case SEPARATE_NON_ADAPTIVE:
52549 + case SEPARATE_ADAPTIVE:
52550 + case NON_SEPARATE_SERVICE:
52551 + case NON_SEPARATE_TUNNELS:
52552 + i = l = trunk_type;
52553 + break;
52554 + case ALL_TRUNKS:
52555 + i = 0;
52556 + l = ALL_TRUNKS - 1;
52557 + break;
52558 + default:
52559 + zlog_err ("\ndefault case %s %d", __FILE__, __LINE__);
52560 + i = 0;
52561 + l = ALL_TRUNKS - 1;
52564 + memset (&trunk_key, 0, sizeof (TRUNK_KEY));
52565 + trunk_key.Dest = PsbKey->Session.Dest;
52566 + for (; i <= l; i++)
52568 + if ((pTree = GetPatriciaTree (i)) == NULL)
52569 + continue;
52570 + if ((pTrunkEntry =
52571 + (TRUNK_ENTRY *) patricia_tree_get (pTree,
52572 + (const uns8 *) &trunk_key)) !=
52573 + NULL)
52575 + RSVP_TUNNEL_PROPERTIES *pTunnel = pTrunkEntry->Lsps;
52576 + while (pTunnel != NULL)
52578 + if (pTunnel->TunnelId == PsbKey->Session.TunnelId)
52580 + *ppTunnel = pTunnel;
52581 + return TRUE;
52583 + pTunnel = pTunnel->next;
52587 + return FALSE;
52590 +uns32
52591 +NewRsvpLsp (RSVP_TUNNEL_PROPERTIES * pTunnel,
52592 + RSVP_LSP_PROPERTIES ** ppRsvpLsp)
52594 + RSVP_LSP_PROPERTIES *pRsvpLsp = pTunnel->properties;
52596 + if (pTunnel->properties == NULL)
52598 + if ((pTunnel->properties =
52599 + (RSVP_LSP_PROPERTIES *) XMALLOC (MTYPE_TE,
52600 + sizeof (RSVP_LSP_PROPERTIES))) ==
52601 + NULL)
52603 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
52604 + return E_ERR;
52606 + memset (pTunnel->properties, 0, sizeof (RSVP_LSP_PROPERTIES));
52607 + *ppRsvpLsp = pTunnel->properties;
52608 + return E_OK;
52611 + while (pRsvpLsp != NULL)
52613 + if (pRsvpLsp->next == NULL)
52615 + if ((pRsvpLsp->next =
52616 + (RSVP_LSP_PROPERTIES *) XMALLOC (MTYPE_TE,
52617 + sizeof (RSVP_LSP_PROPERTIES)))
52618 + == NULL)
52620 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
52621 + return E_ERR;
52623 + *ppRsvpLsp = pRsvpLsp->next; /* !!! */
52624 + return E_OK;
52626 + pRsvpLsp = pRsvpLsp->next;
52628 + return E_ERR; /* should not be reached */
52631 +uns32
52632 +NewTunnel (PSB_KEY * PsbKey, RSVP_TUNNEL_PROPERTIES ** ppNewTunnel,
52633 + TRUNK_TYPE trunk_type)
52635 + TRUNK_ENTRY *pTrunkEntry;
52636 + RSVP_TUNNEL_PROPERTIES *pTunnel;
52637 + TRUNK_KEY trunk_key;
52638 + PATRICIA_TREE *pTree;
52640 + if ((pTree = GetPatriciaTree (trunk_type)) == NULL)
52642 + zlog_err ("\nno trunk type specified %s %d", __FILE__, __LINE__);
52643 + return E_ERR;
52646 + memset (&trunk_key, 0, sizeof (TRUNK_KEY));
52647 + trunk_key.Dest = PsbKey->Session.Dest;
52649 + if ((pTrunkEntry =
52650 + (TRUNK_ENTRY *) patricia_tree_get (pTree,
52651 + (const uns8 *) &trunk_key)) == NULL)
52653 + if ((pTrunkEntry =
52654 + (TRUNK_ENTRY *) XMALLOC (MTYPE_TE, sizeof (TRUNK_ENTRY))) == NULL)
52656 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
52657 + return E_ERR;
52659 + memset (pTrunkEntry, 0, sizeof (TRUNK_ENTRY));
52660 + pTrunkEntry->trunk_key.Dest = PsbKey->Session.Dest;
52661 + pTrunkEntry->Node.key_info = (uns8 *) & (pTrunkEntry->trunk_key);
52662 + if (patricia_tree_add (pTree, &(pTrunkEntry->Node)) != E_OK)
52664 + XFREE (MTYPE_TE, pTrunkEntry);
52665 + zlog_err ("\ncannot add node to patricia %s %d", __FILE__,
52666 + __LINE__);
52667 + return E_ERR;
52670 + if ((pTunnel =
52671 + (RSVP_TUNNEL_PROPERTIES *) XMALLOC (MTYPE_TE,
52672 + sizeof (RSVP_TUNNEL_PROPERTIES)))
52673 + == NULL)
52675 + zlog_err ("\ncannot allocate memory %s %d", __FILE__, __LINE__);
52676 + if (pTrunkEntry->Lsps == NULL)
52678 + if (patricia_tree_del (pTree, &pTrunkEntry->Node) != E_OK)
52680 + zlog_err ("\ncannot delete node from patricia");
52682 + else
52683 + XFREE (MTYPE_TE, pTrunkEntry);
52685 + return E_ERR;
52687 + pTunnel->TunnelId = PsbKey->Session.TunnelId;
52688 + pTunnel->adaptivity_timer.data.adaptivity_timer_data.key = *PsbKey;
52689 + pTunnel->lsp_setup_timer.data.lsp_setup_data.key = *PsbKey;
52690 + pTunnel->lsp_setup_retry_timer.data.lsp_setup_retry_data.key = *PsbKey;
52691 + pTunnel->cspf_retry_timer.data.cspf_retry_data.key = *PsbKey;
52692 + pTunnel->next = pTrunkEntry->Lsps;
52693 + pTrunkEntry->Lsps = pTunnel;
52694 + pTrunkEntry->TunnelsCounter++;
52695 + *ppNewTunnel = pTunnel;
52696 + return E_OK;
52699 +uns32
52700 +DeleteTunnel (PSB_KEY * PsbKey, TRUNK_TYPE trunk_type)
52702 + TRUNK_KEY trunk_key;
52703 + TRUNK_ENTRY *pTrunkEntry;
52704 + RSVP_TUNNEL_PROPERTIES *pTunnel, *pTunnelPrev = NULL;
52705 + PATRICIA_TREE *pTree;
52707 + if ((pTree = GetPatriciaTree (trunk_type)) == NULL)
52709 + zlog_err ("\ntrunk type is not specified %s %d", __FILE__, __LINE__);
52710 + return E_ERR;
52713 + memset (&trunk_key, 0, sizeof (TRUNK_KEY));
52714 + trunk_key.Dest = PsbKey->Session.Dest;
52715 + if ((pTrunkEntry =
52716 + (TRUNK_ENTRY *) patricia_tree_get (pTree,
52717 + (const uns8 *) &trunk_key)) != NULL)
52719 + pTunnel = pTrunkEntry->Lsps;
52720 + while (pTunnel != NULL)
52722 + if (pTunnel->TunnelId == PsbKey->Session.TunnelId)
52724 + RSVP_LSP_PROPERTIES *pLsp, *pLspNext;
52725 + if (pTrunkEntry->Lsps == pTunnel)
52726 + pTrunkEntry->Lsps = pTrunkEntry->Lsps->next;
52727 + else
52728 + pTunnelPrev->next = pTunnel->next;
52729 + pLsp = pTunnel->properties;
52730 + while (pLsp != NULL)
52732 + if (pLsp->forw_info.path.pErHopsList != NULL)
52733 + XFREE (MTYPE_TE, pLsp->forw_info.path.pErHopsList);
52734 + pLspNext = pLsp->next;
52735 + XFREE (MTYPE_TE, pLsp);
52736 + pLsp = pLspNext;
52738 + XFREE (MTYPE_TE, pTunnel);
52739 + pTrunkEntry->TunnelsCounter--;
52740 + if (pTrunkEntry->Lsps == NULL)
52742 + if (patricia_tree_del (pTree, &pTrunkEntry->Node) != E_OK)
52743 + zlog_err ("\ncannot delete node from patricia %s %d",
52744 + __FILE__, __LINE__);
52745 + else
52746 + XFREE (MTYPE_TE, pTrunkEntry);
52748 + return E_OK;
52750 + pTunnelPrev = pTunnel;
52751 + pTunnel = pTunnel->next;
52754 + return E_ERR;
52757 +void
52758 +TE_RSVPTE_API_RsvpTunnelEstablished (RESV_NOTIFICATION * resv_notif)
52760 + PSB_KEY PsbKey;
52761 + RSVP_TUNNEL_PROPERTIES *pTunnel;
52762 + LSP_SM_NOTIF_DATA *pLspSmNotifData = NULL;
52763 + SM_CALL_T *pCall = NULL;
52764 + int i;
52765 + zlog_info ("entering of RsvpTunnelEstablished");
52766 + memset (&PsbKey, 0, sizeof (PSB_KEY));
52767 + PsbKey.Session = resv_notif->RsbKey.Session;
52769 + if (FindTunnel (&PsbKey, &pTunnel, ALL_TRUNKS) == FALSE)
52771 + zlog_err ("\nunexpected TUNNEL Dest %x Tunnel ID %x",
52772 + PsbKey.Session.Dest, PsbKey.Session.TunnelId);
52773 + return;
52775 + if (pTunnel->sm_handle == 0) /* one is waiting for this... */
52777 + zlog_err ("\nThere is no SM to process RSVP TUNNEL %x TO %x",
52778 + pTunnel->TunnelId, PsbKey.Session.Dest);
52779 + return;
52781 + if ((pLspSmNotifData =
52782 + (LSP_SM_NOTIF_DATA *) XMALLOC (MTYPE_TE,
52783 + sizeof (LSP_SM_NOTIF_DATA))) == NULL)
52785 + zlog_err ("malloc failed %s %d", __FILE__, __LINE__);
52786 + return;
52788 + pLspSmNotifData->ingress_lsp_notif = SETUP_COMPLETE_NOTIF;
52789 + pLspSmNotifData->PsbKey = PsbKey;
52791 + if (resv_notif->SharedExplicit)
52793 + pLspSmNotifData->data.setup_complete.NumberOfItems =
52794 + resv_notif->u.FilterDataSE.FilterSpecNumber;
52796 + if ((pLspSmNotifData->data.setup_complete.pLspLabel =
52797 + (LSP_LABEL *) XMALLOC (MTYPE_TE,
52798 + sizeof (LSP_LABEL) *
52799 + (pLspSmNotifData->data.setup_complete.
52800 + NumberOfItems))) == NULL)
52802 + zlog_err ("malloc failed %s %d", __FILE__, __LINE__);
52803 + return;
52805 + pLspSmNotifData->data.setup_complete.BW = resv_notif->u.FilterDataSE.BW;
52806 + for (i = 0; i < resv_notif->u.FilterDataSE.FilterSpecNumber; i++)
52808 + pLspSmNotifData->data.setup_complete.pLspLabel[i].LspId
52810 + resv_notif->u.FilterDataSE.FilterDataArraySE[i].FilterSpec.LspId;
52811 + pLspSmNotifData->data.setup_complete.pLspLabel[i].Label =
52812 + resv_notif->u.FilterDataSE.FilterDataArraySE[i].ReceivedLabel;
52813 + zlog_info ("LspId %x Label %x",
52814 + resv_notif->u.FilterDataSE.FilterDataArraySE[i].
52815 + FilterSpec.LspId,
52816 + resv_notif->u.FilterDataSE.FilterDataArraySE[i].
52817 + ReceivedLabel);
52820 + else
52822 + pLspSmNotifData->data.setup_complete.NumberOfItems = 1;
52823 + if ((pLspSmNotifData->data.setup_complete.pLspLabel =
52824 + (LSP_LABEL *) XMALLOC (MTYPE_TE, sizeof (LSP_LABEL))) == NULL)
52826 + zlog_err ("malloc failed %s %d", __FILE__, __LINE__);
52827 + return;
52829 + pLspSmNotifData->data.setup_complete.BW = resv_notif->u.FilterDataFF.BW;
52830 + pLspSmNotifData->data.setup_complete.pLspLabel->LspId
52831 + = resv_notif->u.FilterDataFF.FilterSpec.LspId;
52832 + pLspSmNotifData->data.setup_complete.pLspLabel->Label
52833 + = resv_notif->u.FilterDataFF.ReceivedLabel;
52834 + zlog_info ("LspId %x Label %x",
52835 + resv_notif->u.FilterDataFF.FilterSpec.LspId,
52836 + resv_notif->u.FilterDataFF.ReceivedLabel);
52838 + if (pLspSmNotifData != NULL)
52840 + if ((pCall = sm_gen_sync_event_send ((SM_T *) (pTunnel->sm_handle),
52841 + MPLS_SIGNALING_INGRESS_ESTABLISHED_NOTIFICATION_EVENT,
52842 + pLspSmNotifData)) == NULL)
52844 + zlog_err ("can not invoke sm %s %d", __FILE__, __LINE__);
52846 + sm_call (pCall);
52848 + zlog_info ("leaving of RsvpTunnelEstablished");
52852 +void
52853 +RsvpTunnelsDump ()
52855 + TRUNK_KEY trunk_key;
52856 + TRUNK_ENTRY *pTrunkEntry;
52857 + int i;
52859 + memset (&trunk_key, 0, sizeof (TRUNK_KEY));
52861 + for (i = 0; i < ALL_TRUNKS; i++)
52863 + PATRICIA_TREE *pTree;
52865 + if ((pTree = GetPatriciaTree (i)) == NULL)
52867 + zlog_info ("\ncannot get patricia tree %s %d", __FILE__, __LINE__);
52868 + continue;
52870 + while ((pTrunkEntry =
52871 + (TRUNK_ENTRY *) patricia_tree_getnext (pTree,
52872 + (const uns8 *)
52873 + &trunk_key)) != NULL)
52875 + RSVP_TUNNEL_PROPERTIES *pTunnel = pTrunkEntry->Lsps;
52876 + while (pTunnel != NULL)
52878 + RSVP_LSP_PROPERTIES *pRsvpLsp = pTunnel->properties;
52880 + zlog_info
52881 + ("RSVP TUNNEL %x AllocBW %f ReqBW %f LSP ID %x ReRoute %x",
52882 + pTunnel->TunnelId, pTunnel->AllocatedBW, pTunnel->RequiredBW,
52883 + pTunnel->LspId, pTunnel->ReRoute);
52884 + zlog_info
52885 + ("\nAdjustment Required %x UserLspName %s StaticPath %s Adaptivity %x LspSetup %x LspSetupRetry %x",
52886 + pTunnel->AdjustmentRequired, pTunnel->UserLspName,
52887 + pTunnel->StaticPathName, pTunnel->adaptivity_timer.is_active,
52888 + pTunnel->lsp_setup_timer.is_active,
52889 + pTunnel->lsp_setup_retry_timer.is_active);
52890 + if (pTunnel->sm_handle != 0)
52891 + zlog_info ("\nTunnel's SM %x",
52892 + ((SM_T *) pTunnel->sm_handle)->sm_type);
52894 + while (pRsvpLsp != NULL)
52896 + zlog_info
52897 + ("\nRSVP LSP: LSP ID %x RequestedBW %f Label(out) %x",
52898 + pRsvpLsp->LspId, pRsvpLsp->RequestedBW, pRsvpLsp->Label);
52900 + if (pRsvpLsp->tunneled == FALSE)
52902 + int j;
52903 + zlog_info ("\nPath:");
52904 + for (j = 0; j < pRsvpLsp->forw_info.path.HopCount; j++)
52905 + zlog_info ("\nER HOP#%d %x", j + 1,
52906 + pRsvpLsp->forw_info.path.pErHopsList[j]);
52907 + zlog_info
52908 + ("\nRSVP LSP Backup Info: Merge node %x OutIf %x Protected node %x Bypass label %x Merege node label valid %x Merge node label %x OutIF %x",
52909 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
52910 + frr_key.merge_node,
52911 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
52912 + frr_key.OutIfIndex,
52913 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
52914 + frr_key.protected_node,
52915 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
52916 + BypassTunnelsLabel,
52917 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
52918 + MergeNodeLabelValid,
52919 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
52920 + MergeNodeLabel,
52921 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
52922 + OutIf);
52924 + pRsvpLsp = pRsvpLsp->next;
52926 + pTunnel = pTunnel->next;
52928 + trunk_key = pTrunkEntry->trunk_key;
52933 +void
52934 +UserLspsDump (char *pName, struct vty *vty)
52936 + USER_LSP_LIST *pUserLsp = UserLspListHead;
52939 + while (pUserLsp != NULL)
52941 + RSVP_TUNNEL_PROPERTIES *pTunnel = pUserLsp->lsp->pUserLspTunnels;
52942 + if (pName)
52944 + if (strcmp (pName, pUserLsp->lsp->params.LspName) != 0)
52946 + pUserLsp = pUserLsp->next;
52947 + continue;
52950 + vty_out (vty, "Tunnel's name %s%s",
52951 + pUserLsp->lsp->params.LspName, VTY_NEWLINE);
52952 + vty_out (vty, "Destination %x%s", pUserLsp->lsp->params.to,
52953 + VTY_NEWLINE);
52954 + if (pUserLsp->lsp->params.Primary[0] != '\0')
52955 + vty_out (vty, "Primary path %s%s", pUserLsp->lsp->params.Primary,
52956 + VTY_NEWLINE);
52957 + else
52958 + vty_out (vty, "No primary path%s", VTY_NEWLINE);
52960 + LSP_PATH_SHARED_PARAMS *pParams = &pUserLsp->lsp->params.lsp_params;
52961 + vty_out (vty, "Common tunnel's parameters%s", VTY_NEWLINE);
52962 + vty_out (vty, "Bandwidth %f %s", pParams->BW, VTY_NEWLINE);
52963 + vty_out (vty, "Setup priority %d Hold priority %d%s",
52964 + pParams->setup_priority, pParams->hold_priority,
52965 + VTY_NEWLINE);
52966 + vty_out (vty, "Hop limit %d%s", pParams->hop_limit, VTY_NEWLINE);
52967 + vty_out (vty, "Optimize timer %d%s", pParams->optimize_timer,
52968 + VTY_NEWLINE);
52969 + vty_out (vty, "Record route: %s%s", (pParams->record) ? "yes" : "no",
52970 + VTY_NEWLINE);
52972 + if (pUserLsp->lsp->params.PrimaryPathParams != NULL)
52974 + LSP_PATH_SHARED_PARAMS *pParams =
52975 + pUserLsp->lsp->params.PrimaryPathParams;
52977 + vty_out (vty, "Primary path parameters %s", VTY_NEWLINE);
52978 + vty_out (vty, "Bandwidth %f %s", pParams->BW, VTY_NEWLINE);
52979 + vty_out (vty, "Setup priority %d Hold priority %d%s",
52980 + pParams->setup_priority, pParams->hold_priority,
52981 + VTY_NEWLINE);
52982 + vty_out (vty, "Hop limit %d%s", pParams->hop_limit, VTY_NEWLINE);
52983 + vty_out (vty, "Optimize timer %d%s", pParams->optimize_timer,
52984 + VTY_NEWLINE);
52985 + vty_out (vty, "Record route: %s%s",
52986 + (pParams->record) ? "yes" : "no", VTY_NEWLINE);
52989 + SECONDARY_PATH_LIST *pSecPathList =
52990 + pUserLsp->lsp->params.SecondaryPaths;
52991 + while (pSecPathList != NULL)
52993 + vty_out (vty, "Secondary %s%s", pSecPathList->Secondary,
52994 + VTY_NEWLINE);
52995 + if (pSecPathList->SecondaryPathParams != NULL)
52997 + LSP_PATH_SHARED_PARAMS *pParams =
52998 + pSecPathList->SecondaryPathParams;
52999 + vty_out (vty, "Bandwidth %f %s", pParams->BW, VTY_NEWLINE);
53000 + vty_out (vty, "Setup priority %d Hold priority %d%s",
53001 + pParams->setup_priority, pParams->hold_priority,
53002 + VTY_NEWLINE);
53003 + vty_out (vty, "Hop limit %d%s", pParams->hop_limit,
53004 + VTY_NEWLINE);
53005 + vty_out (vty, "Optimize timer %d%s", pParams->optimize_timer,
53006 + VTY_NEWLINE);
53007 + vty_out (vty, "Record route: %s%s",
53008 + (pParams->record) ? "yes" : "no", VTY_NEWLINE);
53009 + vty_out (vty, "Standby %s%s",
53010 + (pParams->standby) ? "yes" : "no", VTY_NEWLINE);
53012 + pSecPathList = pSecPathList->next;
53015 + while (pTunnel != NULL)
53017 + RSVP_LSP_PROPERTIES *pRsvpLsp = pTunnel->properties;
53018 + vty_out (vty, "Tunnel ID %x%s", pTunnel->TunnelId, VTY_NEWLINE);
53019 + if (pTunnel->LspId)
53021 + vty_out (vty, " is UP%s", VTY_NEWLINE);
53023 + if (pTunnel->StaticPathName[0] != '\0')
53025 + vty_out (vty, "Static Path Name %s%s",
53026 + pTunnel->StaticPathName, VTY_NEWLINE);
53028 + while (pRsvpLsp != NULL)
53030 + vty_out (vty, "LSP ID %x", pRsvpLsp->LspId);
53031 + if (pTunnel->LspId == pRsvpLsp->LspId)
53033 + vty_out (vty, " is installed");
53035 + vty_out (vty, "%s", VTY_NEWLINE);
53036 + if (pRsvpLsp->tunneled == FALSE)
53038 + int k;
53040 + vty_out (vty, "Setup Prio %d Hold Prio %d %s",
53041 + pRsvpLsp->SetupPriority, pRsvpLsp->HoldPriority,
53042 + VTY_NEWLINE);
53043 + vty_out (vty, "ExcludeAny %x IncludeAny %x IncludeAll %x%s",
53044 + pRsvpLsp->ExcludeAny, pRsvpLsp->IncludeAny,
53045 + pRsvpLsp->IncludeAll, VTY_NEWLINE);
53046 + if (pRsvpLsp->FrrDesired)
53048 + vty_out (vty, "FastReRoute desired%s", VTY_NEWLINE);
53050 + if (pRsvpLsp->LabelRecordingDesired)
53052 + vty_out (vty, "Label Recording desired%s", VTY_NEWLINE);
53054 + if (pRsvpLsp->Label)
53056 + vty_out (vty, "Label %x%s", pRsvpLsp->Label,
53057 + VTY_NEWLINE);
53059 + if (pRsvpLsp->RequestedBW)
53061 + vty_out (vty, "Bandwidth %f%s", pRsvpLsp->RequestedBW,
53062 + VTY_NEWLINE);
53064 + vty_out (vty, "Path:%s", VTY_NEWLINE);
53065 + for (k = 0; k < pRsvpLsp->forw_info.path.HopCount; k++)
53067 + vty_out (vty, "HOP %x%s",
53068 + pRsvpLsp->forw_info.path.pErHopsList[k],
53069 + VTY_NEWLINE);
53072 + pRsvpLsp = pRsvpLsp->next;
53074 + pTunnel = pTunnel->next_user_lsp_tunnel;
53076 + if (pName)
53078 + if (strcmp (pName, pUserLsp->lsp->params.LspName) == 0)
53080 + break;
53083 + pUserLsp = pUserLsp->next;
53087 +void
53088 +TE_RSVPTE_API_RsvpResvTear (RESV_TEAR_NOTIF * pResvTearNotif)
53090 + PSB_KEY PsbKey;
53091 + RSVP_TUNNEL_PROPERTIES *pTunnel;
53092 + LSP_SM_NOTIF_DATA *pLspSmNotifData = NULL;
53093 + SM_CALL_T *pCall = NULL;
53094 + zlog_info ("inside of RsvpResvTear");
53095 + memset (&PsbKey, 0, sizeof (PSB_KEY));
53096 + PsbKey.Session = pResvTearNotif->RsbKey.Session;
53098 + if (FindTunnel (&PsbKey, &pTunnel, ALL_TRUNKS) == FALSE)
53100 + zlog_err ("\ncannot find tunnel %x %x %x",
53101 + PsbKey.Session.Dest,
53102 + PsbKey.Session.TunnelId, PsbKey.Session.ExtTunelId);
53103 + return;
53105 + if (pTunnel->sm_handle == 0) /* one is waiting for this... */
53107 + zlog_err ("\nThere is no SM for tunnel %x %x %x",
53108 + PsbKey.Session.Dest,
53109 + PsbKey.Session.TunnelId, PsbKey.Session.ExtTunelId);
53110 + return;
53112 + if ((pLspSmNotifData =
53113 + (LSP_SM_NOTIF_DATA *) XMALLOC (MTYPE_TE,
53114 + sizeof (LSP_SM_NOTIF_DATA))) == NULL)
53116 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
53117 + return;
53119 + pLspSmNotifData->ingress_lsp_notif = TEAR_DOWN_NOTIF;
53120 + pLspSmNotifData->PsbKey.Session = pResvTearNotif->RsbKey.Session;
53121 + pLspSmNotifData->data.tunnel_down.Lsps.LspId =
53122 + pResvTearNotif->FilterSpec.LspId;
53123 + pLspSmNotifData->data.tunnel_down.NumberOfItems = 1;
53124 + if (pLspSmNotifData != NULL)
53127 + zlog_info ("\nDestIP %x Tunnel ID %x LSP ID %x",
53128 + pLspSmNotifData->PsbKey.Session.Dest,
53129 + pLspSmNotifData->PsbKey.Session.TunnelId,
53130 + pLspSmNotifData->data.tunnel_down.Lsps.LspId);
53131 + if ((pCall = sm_gen_sync_event_send ((SM_T *) pTunnel->sm_handle,
53132 + MPLS_SIGNALING_INGRESS_FAILED_NOTIFICATION_EVENT,
53133 + pLspSmNotifData)) == NULL)
53135 + zlog_err ("\ncan not invoke sm %s %d", __FILE__, __LINE__);
53137 + else
53138 + sm_call (pCall);
53142 +void
53143 +TE_RSVPTE_API_RsvpPathErr (PATH_ERR_NOTIF * pPathErrNotif)
53145 + PSB_KEY PsbKey;
53146 + RSVP_TUNNEL_PROPERTIES *pTunnel;
53147 + LSP_SM_NOTIF_DATA *pLspSmNotifData = NULL;
53148 + SM_CALL_T *pCall = NULL;
53149 + zlog_info ("inside of RsvpPathErr");
53150 + memset (&PsbKey, 0, sizeof (PSB_KEY));
53151 + PsbKey.Session = pPathErrNotif->PsbKey.Session;
53153 + if (FindTunnel (&PsbKey, &pTunnel, ALL_TRUNKS) == FALSE)
53155 + zlog_err ("\ncannot find tunnel %x %x %x",
53156 + PsbKey.Session.Dest,
53157 + PsbKey.Session.TunnelId, PsbKey.Session.ExtTunelId);
53158 + return;
53160 + if (pTunnel->sm_handle == 0) /* one is waiting for this... */
53162 + zlog_err ("\nThere is no SM for tunnel %x %x %x",
53163 + PsbKey.Session.Dest,
53164 + PsbKey.Session.TunnelId, PsbKey.Session.ExtTunelId);
53165 + return;
53167 + if ((pLspSmNotifData =
53168 + (LSP_SM_NOTIF_DATA *) XMALLOC (MTYPE_TE,
53169 + sizeof (LSP_SM_NOTIF_DATA))) == NULL)
53171 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
53172 + return;
53174 + if (pPathErrNotif->ErrSpec.ErrCode == NOTIFY_ERR_CODE)
53176 + if (((pPathErrNotif->ErrSpec.ErrVal & 0xC000) == 0)
53177 + && ((pPathErrNotif->ErrSpec.ErrVal & 0xC000) ==
53178 + RRO_TOO_LARGE_4_MTU))
53180 + zlog_info ("Error code %d is not handled yet",
53181 + pPathErrNotif->ErrSpec.ErrCode);
53182 + XFREE (MTYPE_TE, pLspSmNotifData);
53183 + return;
53186 + pLspSmNotifData->ingress_lsp_notif = SETUP_FAILED_NOTIF;
53187 + pLspSmNotifData->PsbKey.Session = pPathErrNotif->PsbKey.Session;
53188 + pLspSmNotifData->data.setup_failed.LspId =
53189 + pPathErrNotif->PsbKey.SenderTemplate.LspId;
53190 + pLspSmNotifData->data.setup_failed.IpAddr = pPathErrNotif->ErrSpec.IpAddr;
53192 + if ((pCall = sm_gen_sync_event_send ((SM_T *) pTunnel->sm_handle,
53193 + MPLS_SIGNALING_INGRESS_FAILED_NOTIFICATION_EVENT,
53194 + pLspSmNotifData)) == NULL)
53196 + zlog_err ("\ncan not invoke sm %s %d", __FILE__, __LINE__);
53198 + else
53199 + sm_call (pCall);
53202 +TRUNK_ENTRY *
53203 +GetTunnelsTrunk (TRUNK_KEY * trunk_key)
53205 + return (TRUNK_ENTRY *) patricia_tree_get (&NonSeparateTunnelsLspsTrunkTree,
53206 + (const uns8 *) trunk_key);
53209 +TRUNK_ENTRY *
53210 +NewTunnelsTrunk (TRUNK_KEY * trunk_key)
53212 + TRUNK_ENTRY *pTrunkEntry;
53214 + if ((pTrunkEntry =
53215 + (TRUNK_ENTRY *) XMALLOC (MTYPE_TE, sizeof (TRUNK_ENTRY))) == NULL)
53217 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
53218 + return NULL;
53220 + if ((pTrunkEntry->pTrunkData =
53221 + (TRUNK_DATA *) XMALLOC (MTYPE_TE, sizeof (TRUNK_DATA))) == NULL)
53223 + XFREE (MTYPE_TE, pTrunkEntry);
53224 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
53225 + return NULL;
53228 + pTrunkEntry->trunk_key = *trunk_key;
53229 + pTrunkEntry->Node.key_info = (uns8 *) & pTrunkEntry->trunk_key;
53231 + if (patricia_tree_add (&NonSeparateTunnelsLspsTrunkTree, &pTrunkEntry->Node)
53232 + != E_OK)
53234 + zlog_err ("\ncannot add node to patricia %s %d", __FILE__, __LINE__);
53235 + return NULL;
53237 + return pTrunkEntry;
53240 +BOOL
53241 +PathsEqual (ER_HOP_L_LIST * pErHopsLList, IPV4_ADDR * pIpAddr, int HopCount)
53243 + int i;
53244 + for (i = 0; ((i < HopCount) && (pErHopsLList != NULL));
53245 + i += 2, pErHopsLList = pErHopsLList->next)
53247 + if (pErHopsLList->er_hop->remote_ip != pIpAddr[i])
53249 + /*zlog_info("\nlocal ip %x %x",pErHopsLList->er_hop->local_ip,pIpAddr[i]); */
53250 + return FALSE;
53253 + return TRUE;
53256 +PATH *
53257 +GetLspPath (RSVP_LSP_PROPERTIES * pRsvpLsp)
53259 + PATH_L_LIST *pPathLList = NULL;
53260 + IPV4_ADDR dest;
53262 + if (pRsvpLsp->tunneled)
53264 + return NULL;
53266 + if (pRsvpLsp->forw_info.path.pErHopsList == NULL)
53268 + return NULL;
53270 + dest =
53271 + pRsvpLsp->forw_info.path.pErHopsList[pRsvpLsp->forw_info.path.HopCount -
53272 + 1];
53274 + if (IsDestinationIntraArea (dest, &pPathLList) != E_OK)
53276 + zlog_err ("\nsome error in IsDestinationIntraArea %s %d ...", __FILE__,
53277 + __LINE__);
53278 + return NULL;
53280 + zlog_info ("\npPathLList %x dest %x", pPathLList, dest);
53281 + while (pPathLList != NULL)
53283 + if ((pPathLList->pPath->PathProperties.PathHopCount >=
53284 + (pRsvpLsp->forw_info.path.HopCount / 2))
53285 + &&
53286 + (PathsEqual
53287 + (pPathLList->pPath->u.er_hops_l_list,
53288 + pRsvpLsp->forw_info.path.pErHopsList,
53289 + pRsvpLsp->forw_info.path.HopCount) == TRUE))
53291 + return pPathLList->pPath;
53293 + pPathLList = pPathLList->next;
53295 + return NULL;
53298 +uns8 TunnelIds[0xFFFF];
53300 +uns16
53301 +NewTunnelId (PSB_KEY * PsbKey)
53303 + uns16 TunnelId = 0;
53304 + uns32 i;
53305 + PATRICIA_TREE *pTree;
53306 + RSVP_TUNNEL_PROPERTIES *pTunnel;
53307 + TRUNK_ENTRY *pTrunkEntry;
53308 + TRUNK_KEY trunk_key;
53310 + memset (&trunk_key, 0, sizeof (TRUNK_KEY));
53311 + memset (TunnelIds, 0, sizeof (uns8) * 0xFFFF);
53313 + trunk_key.Dest = PsbKey->Session.Dest;
53315 + for (i = 0; i < ALL_TRUNKS; i++)
53317 + pTree = GetPatriciaTree (i);
53318 + if ((pTrunkEntry =
53319 + (TRUNK_ENTRY *) patricia_tree_get (pTree,
53320 + (const uns8 *) &trunk_key)) !=
53321 + NULL)
53323 + pTunnel = pTrunkEntry->Lsps;
53324 + while (pTunnel != NULL)
53326 + TunnelIds[pTunnel->TunnelId - 1] = 1;
53327 + pTunnel = pTunnel->next;
53331 + for (i = 0; i < 0xFFFF; i++)
53332 + if (TunnelIds[i] == 0)
53333 + TunnelId = i + 1;
53334 + return TunnelId;
53337 +uns32
53338 +UserLspAdd (USER_LSP * pUserLsp)
53340 + USER_LSP_LIST *pUserLspList;
53342 + if ((pUserLspList =
53343 + (USER_LSP_LIST *) XMALLOC (MTYPE_TE, sizeof (USER_LSP_LIST))) == NULL)
53345 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
53346 + return E_ERR;
53349 + pUserLspList->lsp = pUserLsp;
53350 + pUserLspList->next = UserLspListHead;
53351 + UserLspListHead = pUserLspList;
53352 + return E_OK;
53355 +USER_LSP *
53356 +UserLspGet (char *pLspName)
53358 + USER_LSP_LIST *pUserLsp = UserLspListHead;
53359 + zlog_info ("entering UserLspGet");
53360 + while (pUserLsp != NULL)
53362 + if (strcmp (pLspName, pUserLsp->lsp->params.LspName) == 0)
53364 + zlog_info ("leaving UserLspGet+");
53365 + return pUserLsp->lsp;
53367 + pUserLsp = pUserLsp->next;
53369 + zlog_info ("leaving UserLspGet-");
53370 + return NULL;
53373 +uns32
53374 +UserLspDelete (char *pLspName)
53376 + USER_LSP_LIST *pUserLsp = UserLspListHead, *pUserLspPrev = NULL;
53377 + SECONDARY_PATH_LIST *pSecondaryPathList, *pSecondaryPathListNext;
53379 + while (pUserLsp != NULL)
53381 + if (strcmp (pLspName, pUserLsp->lsp->params.LspName) == 0)
53383 + if (pUserLsp == UserLspListHead)
53384 + UserLspListHead = UserLspListHead->next;
53385 + else
53386 + pUserLspPrev->next = pUserLsp->next;
53387 +#if 0
53388 + if (pUserLsp->lsp->params.FastReroute != NULL)
53389 + XFREE (MTYPE_TE, pUserLsp->lsp->params.FastReroute);
53390 +#endif
53391 + if (pUserLsp->lsp->params.PrimaryPathParams != NULL)
53392 + XFREE (MTYPE_TE, pUserLsp->lsp->params.PrimaryPathParams);
53393 + pSecondaryPathList = pUserLsp->lsp->params.SecondaryPaths;
53394 + while (pSecondaryPathList != NULL)
53396 + if (pSecondaryPathList->SecondaryPathParams != NULL)
53397 + XFREE (MTYPE_TE, pSecondaryPathList->SecondaryPathParams);
53398 + pSecondaryPathListNext = pSecondaryPathList->next;
53399 + XFREE (MTYPE_TE, pSecondaryPathList);
53400 + pSecondaryPathList = pSecondaryPathListNext;
53402 + XFREE (MTYPE_TE, pUserLsp->lsp);
53403 + XFREE (MTYPE_TE, pUserLsp);
53404 + return E_OK;
53406 + pUserLspPrev = pUserLsp;
53407 + pUserLsp = pUserLsp->next;
53409 + return E_ERR;
53412 +void
53413 +UserLspLoop (void (*CallBackFunc) (USER_LSP *, void *), void *data)
53415 + USER_LSP_LIST *pUserLsp = UserLspListHead, *pUserLspNext;
53416 + while (pUserLsp != NULL)
53418 + pUserLspNext = pUserLsp->next;
53419 + CallBackFunc (pUserLsp->lsp, data);
53420 + pUserLsp = pUserLspNext;
53424 +uns16
53425 +GetPimaryTunnelId (char *pLspName)
53427 + USER_LSP_LIST *pUserLsp = UserLspListHead;
53428 + while (pUserLsp != NULL)
53430 + if (strcmp (pLspName, pUserLsp->lsp->params.LspName) == 0)
53432 + if (pUserLsp->lsp->pUserLspTunnels != NULL)
53433 + return pUserLsp->lsp->pUserLspTunnels->TunnelId;
53435 + pUserLsp = pUserLsp->next;
53437 + return 0;
53440 +BOOL
53441 +RightPathCheaper (PATH_PROPERTIES * pLeftPathProp,
53442 + PATH_PROPERTIES * pRightPathProp, uns8 Priority)
53444 + if (pLeftPathProp->PathCost < pRightPathProp->PathCost)
53446 + zlog_info ("\nmore expensive...");
53447 + return FALSE;
53449 + if (pLeftPathProp->PathCost > pRightPathProp->PathCost)
53451 + zlog_info ("\ncheaper....");
53452 + return TRUE;
53454 + if (pLeftPathProp->PathHopCount < pRightPathProp->PathHopCount)
53456 + zlog_info ("\nlonger...");
53457 + return FALSE;
53459 + if (pLeftPathProp->PathHopCount > pRightPathProp->PathHopCount)
53461 + zlog_info ("\nshorter....");
53462 + return TRUE;
53464 + if (pLeftPathProp->PathReservableBW[Priority] >
53465 + pRightPathProp->PathReservableBW[Priority])
53467 + zlog_info ("\nless reservable BW....");
53468 + return FALSE;
53470 + if (pLeftPathProp->PathReservableBW[Priority] <
53471 + pRightPathProp->PathReservableBW[Priority])
53473 + zlog_info ("\nmore reservable BW....");
53474 + return TRUE;
53476 + if (pLeftPathProp->PathMaxLspBW > pRightPathProp->PathMaxLspBW)
53478 + zlog_info ("\nless Max LSP BW....");
53479 + return FALSE;
53481 + if (pLeftPathProp->PathMaxLspBW < pRightPathProp->PathMaxLspBW)
53483 + zlog_info ("\nmore Max LSP BW....");
53484 + return TRUE;
53486 + if (pLeftPathProp->PathMaxReservableBW >
53487 + pRightPathProp->PathMaxReservableBW)
53489 + zlog_info ("\nmore Max Reservable BW....");
53490 + return FALSE;
53492 + if (pLeftPathProp->PathMaxReservableBW <
53493 + pRightPathProp->PathMaxReservableBW)
53495 + zlog_info ("\nless Max Reservable BW....");
53496 + return TRUE;
53498 + return FALSE;
53501 +uns32
53502 +TunnelIfIdRelease (uns32 IfIndex)
53504 + if ((IfIndex < MAX_TUNNELS_IF) && (IfIndex > 6))
53506 + tunnels_if_array[IfIndex] = 0;
53507 + return E_OK;
53509 + return E_ERR;
53512 +INGRESS_API *
53513 +CreateRequest2Signalling (IPV4_ADDR dest,
53514 + uns16 tunnel_id,
53515 + uns32 ErHopsNumber,
53516 + ER_HOP * pErHops,
53517 + float BW,
53518 + uns8 SetupPriority,
53519 + uns8 HoldPriority,
53520 + uns8 Flags,
53521 + uns32 ExcludeAny,
53522 + uns32 IncludeAny, uns32 IncludeAll)
53524 + INGRESS_API *pOpenLspParams;
53525 + int i;
53527 + zlog_info ("entering CreateRequest2Signalling");
53529 + if ((pOpenLspParams =
53530 + (INGRESS_API *) XMALLOC (MTYPE_TE, sizeof (INGRESS_API))) == NULL)
53532 + zlog_err ("\nmalloc failed %s %d...", __FILE__, __LINE__);
53533 + return NULL;
53535 + pOpenLspParams->Egress = dest;
53536 + pOpenLspParams->src_ip = rdb_get_router_id ();
53537 + pOpenLspParams->TunnelId = tunnel_id;
53538 + pOpenLspParams->BW = BW;
53539 + pOpenLspParams->HopNum = ErHopsNumber;
53540 + for (i = 0; i < pOpenLspParams->HopNum; i++, pErHops++)
53542 + pOpenLspParams->Path[i].IpAddr = pErHops->IpAddr;
53543 + pOpenLspParams->Path[i].PrefixLength = pErHops->PrefixLength;
53544 + pOpenLspParams->Path[i].Loose = pErHops->Loose;
53546 + pOpenLspParams->Shared = TRUE;
53547 + if (Flags & LABEL_RECORDING_DESIRED)
53548 + pOpenLspParams->LabelRecordingDesired = TRUE;
53549 + if (Flags & LOCAL_PROTECTION_DESIRED)
53550 + pOpenLspParams->FrrDesired = TRUE;
53551 + pOpenLspParams->SetPrio = SetupPriority;
53552 + pOpenLspParams->HoldPrio = HoldPriority;
53553 + pOpenLspParams->ExcludeAny = ExcludeAny;
53554 + pOpenLspParams->IncludeAny = IncludeAny;
53555 + pOpenLspParams->IncludeAll = IncludeAll;
53556 + zlog_info ("leaving CreateRequest2Signalling");
53557 + return pOpenLspParams;
53559 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_common.h quagga-mpls/rsvpd/te_common.h
53560 --- quagga/rsvpd/te_common.h 1969-12-31 18:00:00.000000000 -0600
53561 +++ quagga-mpls/rsvpd/te_common.h 2007-06-18 23:55:58.000000000 -0500
53562 @@ -0,0 +1,115 @@
53564 +#ifndef __COMMON_PROC_H__
53565 +#define __COMMON_PROC_H__
53567 +typedef enum
53569 + LSP_SM,
53570 + TRANSIT_LSP_SM,
53571 + CONSTRAINT_ROUTE_RESOLUTION_SM,
53572 + FAST_REROUTE_SM,
53573 + MAX_SM
53574 +} SM_E;
53576 +typedef enum
53578 + USER_LSP_REQUEST_EVENT,
53579 + INGRESS_LSP_REQUEST_EVENT,
53580 + INGRESS_LSP_DELETE_REQUEST_EVENT,
53581 + INGRESS_LSP_OPERATION_COMPLETE_EVENT,
53582 + INGRESS_LSP_OPERATION_FAILED_EVENT,
53583 + TRANSIT_REQ_EVENT,
53584 + SLA_USER_REQUEST_EVENT,
53585 + SLA_DELETE_USER_REQUEST_EVENT,
53586 + CONSTRAINT_ROUTE_RESOLUTION_REQ_EVENT,
53587 + CONSTRAINT_ROUTE_RESOLVED_EVENT,
53588 + CONSTRAINT_ROUTE_RESOLVE_FAILED_EVENT,
53589 + CSPF_REPLY_EVENT,
53590 + DYNAMIC_ADAPTATION_REQ_EVENT,
53591 + SLA_ADAPTATION_REQ_EVENT,
53592 + SLA_ADAPTATION_COMPLETE_EVENT,
53593 + SLA_ADAPTATION_FAILED_EVENT,
53594 + MPLS_SIGNALING_INGRESS_ESTABLISHED_NOTIFICATION_EVENT,
53595 + MPLS_SIGNALING_INGRESS_FAILED_NOTIFICATION_EVENT,
53596 + LSP_SETUP_TIMER_EXPIRY,
53597 + ADAPTIVITY_TIMER_EXPIRY,
53598 + RETRY_TIMER_EXPIRY,
53599 + BYPASS_SETUP_REQ_EVENT,
53600 + RRO_CHANGED_EVENT,
53601 + CSPF_RETRY_EVENT,
53602 + SM_MAX_EVENT
53603 +} SM_EVENT_E;
53605 +typedef struct
53607 + SM_EVENT_E event;
53608 + void *data;
53609 +} SM_EVENT_T;
53611 +typedef struct _sm_t_
53613 + SM_E sm_type;
53614 + int state;
53615 + struct _sm_t_ *caller;
53616 + void *data;
53617 +} SM_T;
53619 +typedef struct
53621 + SM_T *sm;
53622 + SM_EVENT_T *sm_data;
53623 +} SM_CALL_T;
53626 +#define INIT_STATE 1
53628 +typedef void (*LSP_LOOP_CALLBACK_T) (USER_LSP *, void *);
53630 +INGRESS_API *CreateRequest2Signalling (IPV4_ADDR dest,
53631 + uns16 tunnel_id,
53632 + uns32 ErHopsNumber,
53633 + ER_HOP * pErHops,
53634 + float BW,
53635 + uns8 SetupPriority,
53636 + uns8 HoldPriority,
53637 + uns8 Flags,
53638 + uns32 ExcludeAny,
53639 + uns32 IncludeAny, uns32 IncludeAll);
53640 +BOOL RightPathCheaper (PATH_PROPERTIES * pLeftPathProp,
53641 + PATH_PROPERTIES * pRightPathProp, uns8 Priority);
53642 +uns16 GetPimaryTunnelId (char *pLspName);
53643 +uns32 UserLspDelete (char *pLspName);
53644 +USER_LSP *UserLspGet (char *pLspName);
53645 +uns32 UserLspAdd (USER_LSP * pUserLsp);
53646 +uns16 NewTunnelId (PSB_KEY * PsbKey);
53647 +PATH *GetLspPath (RSVP_LSP_PROPERTIES * pRsvpLsp);
53648 +BOOL PathsEqual (ER_HOP_L_LIST * pErHopsLList, IPV4_ADDR * pIpAddr,
53649 + int HopCount);
53650 +TRUNK_ENTRY *NewTunnelsTrunk (TRUNK_KEY * trunk_key);
53651 +TRUNK_ENTRY *GetTunnelsTrunk (TRUNK_KEY * trunk_key);
53652 +void TE_RSVPTE_API_RsvpPathErr (PATH_ERR_NOTIF * pPathErrNotif);
53653 +void TE_RSVPTE_API_RsvpResvTear (RESV_TEAR_NOTIF * pResvTearNotif);
53654 +//void UserLspsDump(char *pName,int PortNum);
53655 +void RsvpTunnelsDump ();
53656 +void TE_RSVPTE_API_RsvpTunnelEstablished (RESV_NOTIFICATION * resv_notif);
53657 +uns32 DeleteTunnel (PSB_KEY * PsbKey, TRUNK_TYPE trunk_type);
53658 +uns32 NewTunnel (PSB_KEY * PsbKey, RSVP_TUNNEL_PROPERTIES ** ppNewTunnel,
53659 + TRUNK_TYPE trunk_type);
53660 +uns32 NewRsvpLsp (RSVP_TUNNEL_PROPERTIES * pTunnel,
53661 + RSVP_LSP_PROPERTIES ** ppRsvpLsp);
53662 +BOOL FindTunnel (PSB_KEY * PsbKey, RSVP_TUNNEL_PROPERTIES ** ppTunnel,
53663 + TRUNK_TYPE trunk_type);
53664 +uns32 TeApplicationInit ();
53665 +void te_stop_timer (TE_TMR * tmr);
53666 +uns32 te_start_timer (TE_TMR * tmr, TE_TMR_E type, uns32 period);
53667 +void sm_call (SM_CALL_T * sm_packet);
53668 +void sm_gen_free (SM_T * sm);
53669 +SM_T *sm_gen_alloc (SM_T * caller, SM_E sm_type);
53670 +SM_CALL_T *sm_gen_sync_event_send (SM_T * sm, SM_EVENT_E event, void *data);
53671 +int sm_gen_async_event_send (SM_T * sm, SM_EVENT_E event, void *data);
53672 +void sm_gen_event_trace (SM_E event);
53673 +void UserLspLoop (void (*CallBackFunc) (USER_LSP *, void *), void *data);
53674 +void UserLspsDump (char *pName, struct vty *vty);
53675 +uns32 NewTunnelIfId (IPV4_ADDR dest, uns32 IfIndex);
53677 +#endif
53678 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_crr.c quagga-mpls/rsvpd/te_crr.c
53679 --- quagga/rsvpd/te_crr.c 1969-12-31 18:00:00.000000000 -0600
53680 +++ quagga-mpls/rsvpd/te_crr.c 2007-06-19 00:10:52.000000000 -0500
53681 @@ -0,0 +1,2095 @@
53682 +/* Module: constraint_route_resolution.c
53683 + Contains: TE application constraint route resolution
53684 + state machine
53685 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
53686 + */
53688 +#include "te.h"
53689 +#include "te_cspf.h"
53691 +static E_RC CreateConstraintRouteResReq (SM_T * pSm, int handle);
53693 +static uns32 InterAreaConstraintRouteResolution (SM_T * pSm,
53694 + CONSTRAINT_ROUTE_RESOLUTION_ARGS
53695 + * args);
53696 +static uns32 IntraAreaConstraintRouteResolution (SM_T * pSm,
53697 + CONSTRAINT_ROUTE_RESOLUTION_ARGS
53698 + * args);
53699 +static uns32 NextHopConstraintRouteResolution (SM_T * pSm,
53700 + CONSTRAINT_ROUTE_RESOLUTION_ARGS
53701 + * args);
53702 +static uns32 DetermineDestinationType (SM_T * pSm,
53703 + CONSTRAINT_ROUTE_RESOLUTION_ARGS *
53704 + args, DESTINATION_TYPE_E * type);
53705 +static BOOL OwnTunnel (IPV4_ADDR addr);
53707 +static BOOL TunnelsTunnel2BeModified (CONSTRAINT_ROUTE_RESOLUTION_ARGS * args,
53708 + SM_T * pSm);
53710 +static BOOL SummaryAdmissionControl (SUMMARY_PROPERTIES * pSummaryProperties,
53711 + CONSTRAINT_ROUTE_RESOLUTION_ARGS * args);
53712 +static RSVP_TUNNEL_PROPERTIES *FindTunnelByPath (TRUNK_ENTRY * pTrunkEntry,
53713 + PATH * pPath);
53715 +static BOOL SummaryTieBreak (SUMMARY_PROPERTIES * pLeftSummary,
53716 + PATH * pLeftPath,
53717 + SUMMARY_PROPERTIES * pRightSummary,
53718 + PATH * pRightPath, uns8 Priority);
53719 +static int SelectAreaBorder (SM_T * pSm, ABRS_L_LIST * pAbrs,
53720 + CONSTRAINT_ROUTE_RESOLUTION_ARGS * args,
53721 + ABR ** ppAbr, PATH ** ppPath);
53722 +static BOOL PathAdmissionControl (PATH * pPath,
53723 + CONSTRAINT_ROUTE_RESOLUTION_ARGS * args);
53725 +static uns32 GetSharedHopsNumber (PATH * pPath,
53726 + CONSTRAINT_ROUTE_RESOLUTION_ARGS * args);
53728 +static BOOL PathTieBreak (PATH * pLeftPath,
53729 + PATH * pRigthPath,
53730 + CONSTRAINT_ROUTE_RESOLUTION_ARGS * args,
53731 + uns32 * CurrentSharedHopsNumber);
53733 +static BOOL LinkAdmissionControl (TE_LINK_PROPERTIES * pTeLinkProperties,
53734 + COMPONENT_LINK * pComponentLink,
53735 + CONSTRAINT_ROUTE_RESOLUTION_ARGS * args);
53737 +static uns32 DetermineDestinationType (SM_T * pSm,
53738 + CONSTRAINT_ROUTE_RESOLUTION_ARGS *
53739 + args, DESTINATION_TYPE_E * type);
53741 +static SM_CALL_T *constraint_route_resolution_sm_dynamic_adaptivity (SM_T *
53742 + pSm,
53743 + SM_EVENT_T
53745 + sm_event);
53746 +static SM_CALL_T *constraint_route_resolution_sm_empty_handler (SM_T * pSm,
53747 + SM_EVENT_T *
53748 + sm_data);
53749 +static SM_CALL_T *constraint_route_resolution_sm_init (SM_T * pSm,
53750 + SM_EVENT_T * sm_event);
53751 +static void constraint_route_resolution_sm_destroy (SM_T * pSm);
53753 +BOOL TunnelsAutoSetup = FALSE;
53754 +BOOL DontUsePathCash = FALSE;
53756 +void
53757 +TunnelsAutoSetupEnable ()
53759 + TunnelsAutoSetup = TRUE;
53762 +void
53763 +TunnelsAutoSetupDisable ()
53765 + TunnelsAutoSetup = FALSE;
53768 +CSPF_REQUEST *
53769 +CreateCspfRequest (int Dest /* IN */ ,
53770 + int Priority /* IN */ ,
53771 + int ExcludeColorMask /* IN */ ,
53772 + int IncludeAnyColorMask /* IN */ ,
53773 + int IncludeColorMask /* IN */ ,
53774 + int HopCountLimit /* IN */ ,
53775 + float Bw /* IN */ ,
53776 + int LinkBwCount /* IN */ ,
53777 + LINK_BW * pLinkBw /* IN */ ,
53778 + int Hops2AvoidCount /* IN */ ,
53779 + int *Hops2Avoid /* IN */ ,
53780 + int Hops2ExcludeCount /* IN */ ,
53781 + int *Hops2Exclude /* IN */ ,
53782 + int *Len /* OUT */ ,
53783 + int **ppMessage)
53785 + int size =
53786 + sizeof (CSPF_REQUEST) + LinkBwCount * sizeof (LINK_BW) +
53787 + Hops2AvoidCount * sizeof (int) + Hops2ExcludeCount * sizeof (int) +
53788 + sizeof (int);
53789 + CSPF_REQUEST *pCspfRequest;
53790 + int *pMessage;
53791 + char *pData;
53793 + pMessage = XMALLOC (MTYPE_TE, size);
53795 + if (pMessage == NULL)
53797 + return NULL;
53799 + *pMessage = CSPF_REQ;
53800 + pCspfRequest = (CSPF_REQUEST *) (pMessage + 1);
53801 + pCspfRequest->Destination.s_addr = Dest;
53802 + pCspfRequest->Priority = Priority;
53803 + pCspfRequest->ExcludeColorMask = ExcludeColorMask;
53804 + pCspfRequest->IncludeAnyColorMask = IncludeAnyColorMask;
53805 + pCspfRequest->IncludeColorMask = IncludeColorMask;
53806 + pCspfRequest->HopCountLimit = HopCountLimit;
53807 + pCspfRequest->Bw = Bw;
53808 + pCspfRequest->LinkBwCount = LinkBwCount;
53809 + pCspfRequest->Hops2AvoidCount = Hops2AvoidCount;
53810 + pCspfRequest->Hops2ExcludeCount = Hops2ExcludeCount;
53811 + pCspfRequest->pLinkBw = NULL;
53812 + pCspfRequest->Hops2Avoid = NULL;
53813 + pData = (char *) (pCspfRequest + 1);
53814 + if (LinkBwCount)
53816 + memcpy (pData, pLinkBw, sizeof (LINK_BW) * LinkBwCount);
53817 + pData += sizeof (LINK_BW) * LinkBwCount;
53819 + if (Hops2AvoidCount)
53821 + memcpy (pData, Hops2Avoid, sizeof (int) * Hops2AvoidCount);
53822 + pData += sizeof (int) * Hops2AvoidCount;
53824 + if (Hops2ExcludeCount)
53826 + memcpy (pData, Hops2Exclude, sizeof (int) * Hops2ExcludeCount);
53828 + *Len = size;
53829 + *ppMessage = pMessage;
53830 + return pCspfRequest;
53833 +void
53834 +RegisterClient (int handle, int instance, IPV4_ADDR dest, void *pSm)
53836 + CR_CLIENT_NODE *pCrClientNode;
53837 + CR_CLIENT_KEY key;
53838 + zlog_info ("entering RegisterClient");
53839 + key.handle = handle;
53840 + key.instance = instance;
53842 + if ((pCrClientNode =
53843 + (CR_CLIENT_NODE *) patricia_tree_get (&ConstraintRouteResClientsTree,
53844 + (const uns8 *) &key)) != NULL)
53846 + CR_REQ_NODE *pCrNode;
53847 + CR_REQUESTS_LIST *pCrReqList, *pCrReqListPrev = NULL, *pCrReqList2;
53848 + if ((pCrNode =
53849 + (CR_REQ_NODE *) patricia_tree_get (&ConstraintRouteResReqTree,
53850 + (const uns8 *) &pCrClientNode->
53851 + dest)) != NULL)
53853 + pCrReqList = pCrNode->pCrReqList;
53854 + while (pCrReqList != NULL)
53856 + if (pCrReqList->pParentSm == (void *) handle)
53858 + constraint_route_resolution_sm_destroy (pCrReqList->pSm);
53859 + pCrReqList->pSm = pSm;
53860 + if (pCrClientNode->dest != dest)
53862 + if (pCrReqListPrev == NULL)
53864 + pCrNode->pCrReqList = pCrNode->pCrReqList->next;
53866 + else
53868 + pCrReqListPrev->next = pCrReqList->next;
53870 + pCrReqList->next = NULL;
53871 + if (pCrNode->pCrReqList == NULL)
53873 + patricia_tree_del (&ConstraintRouteResReqTree,
53874 + &pCrNode->Node);
53875 + pCrNode->dest = dest;
53876 + if (patricia_tree_add
53877 + (&ConstraintRouteResReqTree,
53878 + &pCrNode->Node) != E_OK)
53880 + zlog_err ("Cannot add node to patricia %s %d",
53881 + __FILE__, __LINE__);
53884 + if ((pCrReqList2 = pCrNode->pCrReqList) == NULL)
53886 + pCrNode->pCrReqList = pCrReqList;
53888 + else
53890 + while (pCrReqList2->next != NULL)
53891 + pCrReqList2 = pCrReqList2->next;
53892 + pCrReqList2->next = pCrReqList;
53895 + break;
53897 + pCrReqListPrev = pCrReqList;
53898 + pCrReqList = pCrReqList->next;
53901 + pCrClientNode->dest = dest;
53902 +// pCrClientNode->sm = pSm;
53903 + zlog_info ("leaving RegisterClient1");
53904 + return;
53907 + if ((pCrClientNode =
53908 + (CR_CLIENT_NODE *) XMALLOC (MTYPE_TE,
53909 + sizeof (CR_CLIENT_NODE))) == NULL)
53911 + zlog_err ("canot allocate memory %s %d", __FILE__, __LINE__);
53912 + return;
53914 + pCrClientNode->Node.key_info = (uns8 *) & pCrClientNode->key;
53915 + pCrClientNode->key = key;
53916 + pCrClientNode->dest = dest;
53918 + if (patricia_tree_add (&ConstraintRouteResClientsTree, &pCrClientNode->Node)
53919 + != E_OK)
53921 + zlog_err ("Cannot add node to patricia %s %d", __FILE__, __LINE__);
53923 + if (CreateConstraintRouteResReq (pSm, handle) != E_OK)
53925 + zlog_err ("cannot create CR request %s %d", __FILE__, __LINE__);
53927 + zlog_info ("leaving RegisterClient2");
53930 +void
53931 +UnregisterClient (int handle, int TunnelId)
53933 + CR_CLIENT_NODE *pCrClientNode;
53934 + CR_CLIENT_KEY key;
53936 + zlog_info ("entering UnregisterClient");
53938 + key.handle = handle;
53939 + key.instance = TunnelId;
53941 + if ((pCrClientNode =
53942 + (CR_CLIENT_NODE *) patricia_tree_get (&ConstraintRouteResClientsTree,
53943 + (const uns8 *) &key)) != NULL)
53945 + CR_REQ_NODE *pCrNode;
53946 + CR_REQUESTS_LIST *pCrReqList, *pCrReqListPrev = NULL;
53948 + if ((pCrNode =
53949 + (CR_REQ_NODE *) patricia_tree_get (&ConstraintRouteResReqTree,
53950 + (const uns8 *) &pCrClientNode->
53951 + dest)) == NULL)
53953 + zlog_err ("leaving UnregisterClient-");
53954 + return;
53957 + pCrReqList = pCrNode->pCrReqList;
53958 + while (pCrReqList != NULL)
53960 + if (pCrReqList->pParentSm == (void *) handle)
53962 + if (pCrReqListPrev == NULL)
53964 + pCrNode->pCrReqList = pCrNode->pCrReqList->next;
53965 + if (pCrNode->pCrReqList == NULL)
53967 + if (patricia_tree_del
53968 + (&ConstraintRouteResReqTree,
53969 + &pCrNode->Node) != E_OK)
53971 + zlog_err ("Cannot delete node from patricia %s %d",
53972 + __FILE__, __LINE__);
53973 + return;
53975 + else
53977 + XFREE (MTYPE_TE, pCrNode);
53981 + else
53983 + pCrReqListPrev->next = pCrReqList->next;
53985 + if (patricia_tree_del
53986 + (&ConstraintRouteResClientsTree,
53987 + &pCrClientNode->Node) != E_OK)
53989 + zlog_err ("Cannot delete a node from patricia %s %d",
53990 + __FILE__, __LINE__);
53991 + return;
53993 + constraint_route_resolution_sm_destroy (pCrReqList->pSm);
53994 + XFREE (MTYPE_TE, pCrReqList);
53995 + XFREE (MTYPE_TE, pCrClientNode);
53996 + zlog_info ("leaving UnregisterClient2");
53997 + return;
53999 + pCrReqListPrev = pCrReqList;
54000 + pCrReqList = pCrReqList->next;
54003 + zlog_info ("leaving UnregisterClient3");
54006 +int
54007 +constraint_route_resolution_sm_cspf_reply (SM_T * pSm)
54009 + SM_CALL_T *pCall = NULL;
54010 + SM_EVENT_E event = CONSTRAINT_ROUTE_RESOLVE_FAILED_EVENT;
54011 + CONSTRAINT_ROUTE_RESOLUTION_ARGS *pCrArgs =
54012 + ((CONSTRAINT_ROUTE_RESOLUTION_SM_DATA *) pSm->data)->args;
54014 + if (IntraAreaConstraintRouteResolution (pSm, pCrArgs) != E_OK)
54016 + zlog_info ("intra-area constraint route resolution is failed");
54017 + if ((pCall =
54018 + sm_gen_sync_event_send (pSm->caller, event, pCrArgs)) == NULL)
54020 + zlog_err ("cannot send sycn event %s %d", __FILE__, __LINE__);
54021 + constraint_route_resolution_sm_destroy (pSm);
54023 + else
54025 + constraint_route_resolution_sm_destroy (pSm);
54026 + sm_call (pCall);
54028 + return 1;
54030 + switch (pCrArgs->rc)
54032 + case OUTPUT_LSP_SETUP_PENDING:
54033 + pSm->state = CONSTAINT_ROUTE_RESOLUTION_SM_ADAPTIVITY_STATE;
54034 + return 0;
54035 + case OUTPUT_EGRESS:
54036 + case OUTPUT_LSP:
54037 + case OUTPUT_NEXT_HOP:
54038 + case OUTPUT_PATH:
54039 + event = CONSTRAINT_ROUTE_RESOLVED_EVENT;
54040 + break;
54041 + case OUTPUT_CAC_FAILED:
54042 + case OUTPUT_UNREACHABLE:
54043 + event = CONSTRAINT_ROUTE_RESOLVE_FAILED_EVENT;
54044 + break;
54045 + default:
54046 + zlog_err ("default case %s %d", __FILE__, __LINE__);
54047 + event = CONSTRAINT_ROUTE_RESOLVE_FAILED_EVENT;
54049 + if ((pCall = sm_gen_sync_event_send (pSm->caller, event, pCrArgs)) == NULL)
54051 + zlog_err ("cannot send sycn event %s %d", __FILE__, __LINE__);
54052 + return 1;
54054 + sm_call (pCall);
54055 + return (event == CONSTRAINT_ROUTE_RESOLVE_FAILED_EVENT);
54058 +void
54059 +CspfReply (IPV4_ADDR dest, void *handle)
54061 + CR_REQ_NODE *pCrNode;
54062 + CR_REQUESTS_LIST *pCrReqList, *pCrReqListPrev = NULL, *pCrReqListNew;
54063 + CR_CLIENT_NODE *pCrClientNode;
54064 + CR_CLIENT_KEY key;
54065 + int rc;
54066 + zlog_info ("entering CspfReply");
54067 + if ((pCrNode =
54068 + (CR_REQ_NODE *) patricia_tree_get (&ConstraintRouteResReqTree,
54069 + (const uns8 *) &dest)) == NULL)
54071 + zlog_info ("leaving CspfReply1 %x", dest);
54072 + return;
54074 + pCrReqList = pCrNode->pCrReqList;
54076 + while (pCrReqList != NULL)
54078 + if (pCrReqList->pSm == handle)
54080 + CONSTRAINT_ROUTE_RESOLUTION_ARGS *pCrArgs;
54081 + int TunnelId;
54082 + SM_T *pSm;
54083 + pSm = pCrReqList->pSm;
54084 + pCrArgs =
54085 + ((CONSTRAINT_ROUTE_RESOLUTION_SM_DATA *) (pSm->data))->args;
54086 + TunnelId = pCrArgs->PsbKey.Session.TunnelId;
54087 + constraint_route_resolution_sm_cspf_reply (pSm);
54088 + //UnregisterClient(pSm->caller,TunnelId);
54089 + key.handle = (int) pSm->caller;
54090 + key.instance = TunnelId;
54091 + if ((pCrClientNode =
54092 + (CR_CLIENT_NODE *)
54093 + patricia_tree_get (&ConstraintRouteResClientsTree,
54094 + (const uns8 *) &key)) != NULL)
54096 + if (patricia_tree_del
54097 + (&ConstraintRouteResClientsTree,
54098 + &pCrClientNode->Node) != E_OK)
54100 + zlog_err ("Cannot delete a node from patricia %s %d",
54101 + __FILE__, __LINE__);
54103 + else
54105 + XFREE (MTYPE_TE, pCrClientNode);
54108 + else
54110 + zlog_err ("Cannot get a node from patricia %s %d", __FILE__,
54111 + __LINE__);
54113 + if (pCrReqListPrev == NULL)
54115 + pCrNode->pCrReqList = pCrNode->pCrReqList->next;
54116 + if (pCrNode->pCrReqList == NULL)
54118 + if (patricia_tree_del
54119 + (&ConstraintRouteResReqTree, &pCrNode->Node) != E_OK)
54121 + zlog_err ("Cannot delete node from patricia %s %d",
54122 + __FILE__, __LINE__);
54124 + else
54126 + XFREE (MTYPE_TE, pCrNode);
54128 + XFREE (MTYPE_TE, pCrReqList);
54129 + zlog_info ("leaving CspfReply2");
54130 + return;
54133 + else
54135 + pCrReqListPrev->next = pCrReqList->next;
54136 + XFREE (MTYPE_TE, pCrReqList);
54138 + break;
54140 + pCrReqListPrev = pCrReqList;
54141 + pCrReqList = pCrReqList->next;
54144 + if (DontUsePathCash)
54146 + return;
54148 + pCrReqListPrev = NULL;
54149 + pCrReqList = pCrNode->pCrReqList;
54150 + rc = 0;
54151 + while (pCrReqList != NULL)
54153 + CONSTRAINT_ROUTE_RESOLUTION_ARGS *pCrArgs;
54154 + int TunnelId;
54155 + SM_T *pSm;
54156 + pSm = pCrReqList->pSm;
54157 + pCrArgs = ((CONSTRAINT_ROUTE_RESOLUTION_SM_DATA *) (pSm->data))->args;
54158 + TunnelId = pCrArgs->PsbKey.Session.TunnelId;
54159 + if ((rc = constraint_route_resolution_sm_cspf_reply (pSm)) == 0)
54161 + key.handle = (int) pSm->caller;
54162 + key.instance = TunnelId;
54163 + //zlog_info("trying to get RouteResClient node (%s %d): handle %x tunnel_id %x sm %x",__FILE__,__LINE__,handle,TunnelId,pSm);
54164 + if ((pCrClientNode =
54165 + (CR_CLIENT_NODE *)
54166 + patricia_tree_get (&ConstraintRouteResClientsTree,
54167 + (const uns8 *) &key)) != NULL)
54169 + if (patricia_tree_del
54170 + (&ConstraintRouteResClientsTree,
54171 + &pCrClientNode->Node) != E_OK)
54173 + zlog_err ("Cannot delete a node from patricia %s %d",
54174 + __FILE__, __LINE__);
54176 + else
54178 + XFREE (MTYPE_TE, pCrClientNode);
54181 + else
54183 + zlog_err ("Cannot get a node from patricia %s %d", __FILE__,
54184 + __LINE__);
54186 + if (pCrReqListPrev == NULL)
54188 + pCrNode->pCrReqList = pCrNode->pCrReqList->next;
54190 + else
54192 + pCrReqListPrev->next = pCrReqList->next;
54194 + pCrReqListNew = pCrReqList->next;
54195 + XFREE (MTYPE_TE, pCrReqList);
54196 + pCrReqList = pCrReqListNew;
54197 + if (pCrNode->pCrReqList == NULL)
54199 + if (patricia_tree_del
54200 + (&ConstraintRouteResReqTree, &pCrNode->Node) != E_OK)
54202 + zlog_err ("Cannot delete node from patricia %s %d",
54203 + __FILE__, __LINE__);
54205 + else
54207 + XFREE (MTYPE_TE, pCrNode);
54209 + XFREE (MTYPE_TE, pCrReqList);
54210 + zlog_info ("leaving CspfReply3");
54211 + return;
54214 + else
54216 + pCrReqListPrev = pCrReqList;
54217 + pCrReqList = pCrReqList->next;
54220 + zlog_info ("leaving CspfReply4");
54223 +E_RC
54224 +CreateConstraintRouteResReq (SM_T * pSm, int handle)
54226 + CR_REQ_NODE *pCrNode;
54227 + CR_REQUESTS_LIST *pCrReqList, *pCrReqListNew;
54228 + CONSTRAINT_ROUTE_RESOLUTION_ARGS *pCrArgs;
54230 + zlog_info ("entering CreateConstraintRouteResReq");
54232 + pCrArgs = ((CONSTRAINT_ROUTE_RESOLUTION_SM_DATA *) (pSm->data))->args;
54234 + if ((pCrReqListNew =
54235 + (CR_REQUESTS_LIST *) XMALLOC (MTYPE_TE,
54236 + sizeof (CR_REQUESTS_LIST))) == NULL)
54238 + zlog_err ("malloc failed %s %d", __FILE__, __LINE__);
54239 + return E_ERR;
54241 + pCrReqListNew->pSm = pSm;
54242 + pCrReqListNew->pParentSm = (void *) handle;
54243 + //zlog_info("handle %x tunnel_id %x sm %x",handle,pCrArgs->dest,pSm);
54244 + if ((pCrNode =
54245 + (CR_REQ_NODE *) patricia_tree_get (&ConstraintRouteResReqTree,
54246 + (const uns8 *) &pCrArgs->dest)) ==
54247 + NULL)
54249 + if ((pCrNode =
54250 + (CR_REQ_NODE *) XMALLOC (MTYPE_TE, sizeof (CR_REQ_NODE))) == NULL)
54252 + zlog_err ("malloc failed %s %d", __FILE__, __LINE__);
54253 + XFREE (MTYPE_TE, pCrReqListNew);
54254 + return E_ERR;
54256 + pCrNode->dest = pCrArgs->dest;
54257 + pCrNode->Node.key_info = (uns8 *) & pCrNode->dest;
54258 + pCrNode->pCrReqList = pCrReqListNew;
54259 + if (patricia_tree_add (&ConstraintRouteResReqTree, &pCrNode->Node) !=
54260 + E_OK)
54262 + zlog_err ("Cannot add node to patricia %s %d", __FILE__, __LINE__);
54263 + XFREE (MTYPE_TE, pCrReqListNew);
54264 + XFREE (MTYPE_TE, pCrNode);
54265 + return E_ERR;
54267 + zlog_info ("leaving CreateConstraintRouteResReq0 %x",
54268 + ((CONSTRAINT_ROUTE_RESOLUTION_SM_DATA *) (pSm->data))->args);
54269 + return E_OK;
54271 + pCrReqList = pCrNode->pCrReqList;
54272 + if (!pCrReqList)
54274 + pCrNode->pCrReqList = pCrReqListNew;
54275 + zlog_info ("leaving CreateConstraintRouteResReq1 %x",
54276 + ((CONSTRAINT_ROUTE_RESOLUTION_SM_DATA *) (pSm->data))->args);
54277 + return E_OK;
54279 + while (pCrReqList->next != NULL)
54280 + pCrReqList = pCrReqList->next;
54281 + pCrReqList->next = pCrReqListNew;
54282 + zlog_info ("leaving CreateConstraintRouteResReq2");
54283 + return E_OK;
54286 +static SM_CALL_T *
54287 +constraint_route_resolution_sm_empty_handler (SM_T * pSm,
54288 + SM_EVENT_T * sm_data)
54290 + zlog_err ("\nconstraint_route_resolution_sm_empty_handler, state %d",
54291 + pSm->state);
54292 + return NULL;
54295 +static SM_CALL_T *
54296 +constraint_route_resolution_sm_init (SM_T * pSm, SM_EVENT_T * sm_event)
54298 + SM_CALL_T *pCall = NULL;
54299 + CONSTRAINT_ROUTE_RESOLUTION_ARGS *pCrArgs = NULL;
54300 + DESTINATION_TYPE_E type;
54301 + CSPF_REQUEST *pCspfRequest;
54302 + int Len = 0, *pMessage;
54303 + SM_EVENT_E event = CONSTRAINT_ROUTE_RESOLVE_FAILED_EVENT;
54306 + if ((pSm->data =
54307 + (CONSTRAINT_ROUTE_RESOLUTION_SM_DATA *) XMALLOC (MTYPE_TE,
54308 + sizeof
54309 + (CONSTRAINT_ROUTE_RESOLUTION_SM_DATA)))
54310 + == NULL)
54312 + zlog_err ("malloc failed %s %d", __FILE__, __LINE__);
54313 + if ((pCall =
54314 + sm_gen_sync_event_send (pSm->caller, event, pCrArgs)) == NULL)
54316 + zlog_err ("cannot send sycn event %s %d", __FILE__, __LINE__);
54317 + constraint_route_resolution_sm_destroy (pSm);
54318 + return NULL;
54320 + else
54322 + constraint_route_resolution_sm_destroy (pSm);
54323 + return pCall;
54326 + switch (sm_event->event)
54328 + case CONSTRAINT_ROUTE_RESOLUTION_REQ_EVENT:
54329 + sm_gen_event_trace (sm_event->event);
54330 + pCrArgs = sm_event->data;
54331 + if ((!pSm) || (!pSm->data) || (!pCrArgs))
54333 + printf ("fatal error: %x %x %x %s %d", pSm,
54334 + (int) ((pSm) ? pSm->data : 0), (int) pCrArgs, __FILE__,
54335 + __LINE__);
54336 + exit (0);
54338 + ((CONSTRAINT_ROUTE_RESOLUTION_SM_DATA *) pSm->data)->args = pCrArgs;
54340 + if ((DontUsePathCash) || (pCrArgs->AvoidHopNumber != 0))
54342 + if ((pCspfRequest = CreateCspfRequest (pCrArgs->dest,
54343 + pCrArgs->SetupPriority,
54344 + pCrArgs->ExclColorMask,
54345 + pCrArgs->InclAnyColorMask,
54346 + pCrArgs->InclColorMask,
54347 + pCrArgs->HopCount,
54348 + pCrArgs->BW,
54349 + pCrArgs->LinkBwNumber,
54350 + (LINK_BW *) pCrArgs->pLinkBw,
54351 + pCrArgs->AvoidHopNumber,
54352 + pCrArgs->AvoidHopsArray,
54353 + pCrArgs->ExcludeHopNumber,
54354 + pCrArgs->ExcludeHopsArray,
54355 + &Len, &pMessage)) == NULL)
54357 + return NULL;
54359 + pCspfRequest->handle = pSm;
54360 + te_send_msg (pMessage, Len);
54361 + XFREE (MTYPE_TE, pMessage);
54362 + RegisterClient ((int) pSm->caller,
54363 + pCrArgs->PsbKey.Session.TunnelId,
54364 + pCrArgs->dest, pSm);
54365 + return NULL;
54368 + if (TunnelsTunnel2BeModified (pCrArgs, pSm) == TRUE)
54370 + pSm->state = CONSTAINT_ROUTE_RESOLUTION_SM_ADAPTIVITY_STATE;
54371 + return NULL;
54374 + if (DetermineDestinationType (pSm, pCrArgs, &type) != E_OK)
54376 + zlog_info ("DetermineDestinationType failed...");
54377 + if ((pCall =
54378 + sm_gen_sync_event_send (pSm->caller, event, pCrArgs)) == NULL)
54380 + zlog_err ("cannot send sycn event %s %d", __FILE__, __LINE__);
54381 + constraint_route_resolution_sm_destroy (pSm);
54382 + return NULL;
54384 + else
54386 + constraint_route_resolution_sm_destroy (pSm);
54387 + return pCall;
54390 + switch (type)
54392 + case OUT_OF_AREA_DEST:
54393 + if (InterAreaConstraintRouteResolution (pSm, pCrArgs) != E_OK)
54395 + zlog_info ("inter-area constraint route resolution is failed");
54396 + if ((pCall =
54397 + sm_gen_sync_event_send (pSm->caller, event,
54398 + pCrArgs)) == NULL)
54400 + zlog_err ("cannot send sycn event %s %d", __FILE__,
54401 + __LINE__);
54402 + constraint_route_resolution_sm_destroy (pSm);
54403 + return NULL;
54405 + else
54407 + constraint_route_resolution_sm_destroy (pSm);
54408 + return pCall;
54411 + switch (pCrArgs->rc)
54413 + case OUTPUT_LSP_SETUP_PENDING:
54414 + pSm->state = CONSTAINT_ROUTE_RESOLUTION_SM_ADAPTIVITY_STATE;
54415 + return NULL;
54416 + case OUTPUT_EGRESS:
54417 + case OUTPUT_LSP:
54418 + case OUTPUT_NEXT_HOP:
54419 + case OUTPUT_PATH:
54420 + event = CONSTRAINT_ROUTE_RESOLVED_EVENT;
54421 + break;
54422 + case OUTPUT_CAC_FAILED:
54423 + case OUTPUT_UNREACHABLE:
54424 + if ((pCspfRequest = CreateCspfRequest (pCrArgs->dest,
54425 + pCrArgs->SetupPriority,
54426 + pCrArgs->ExclColorMask,
54427 + pCrArgs->
54428 + InclAnyColorMask,
54429 + pCrArgs->InclColorMask,
54430 + pCrArgs->HopCount,
54431 + pCrArgs->BW,
54432 + pCrArgs->LinkBwNumber,
54433 + (LINK_BW *) pCrArgs->
54434 + pLinkBw,
54435 + pCrArgs->AvoidHopNumber,
54436 + pCrArgs->AvoidHopsArray,
54437 + pCrArgs->
54438 + ExcludeHopNumber,
54439 + pCrArgs->
54440 + ExcludeHopsArray, &Len,
54441 + &pMessage)) == NULL)
54443 + return NULL;
54445 + pCspfRequest->handle = pSm;
54446 + te_send_msg (pMessage, Len);
54447 + XFREE (MTYPE_TE, pMessage);
54448 + RegisterClient ((int) pSm->caller,
54449 + pCrArgs->PsbKey.Session.TunnelId,
54450 + pCrArgs->dest, pSm);
54451 + return NULL;
54452 + default:
54453 + zlog_err ("default case %s %d", __FILE__, __LINE__);
54454 + event = CONSTRAINT_ROUTE_RESOLVE_FAILED_EVENT;
54456 + if ((pCall =
54457 + sm_gen_sync_event_send (pSm->caller, event, pCrArgs)) == NULL)
54459 + zlog_err ("cannot send sycn event %s %d", __FILE__, __LINE__);
54461 + break;
54462 + case INTRA_AREA_DEST:
54463 + if (IntraAreaConstraintRouteResolution (pSm, pCrArgs) != E_OK)
54465 + zlog_info ("intra-area constraint route resolution is failed");
54466 + if ((pCall =
54467 + sm_gen_sync_event_send (pSm->caller, event,
54468 + pCrArgs)) == NULL)
54470 + zlog_err ("cannot send sycn event %s %d", __FILE__,
54471 + __LINE__);
54472 + constraint_route_resolution_sm_destroy (pSm);
54473 + return NULL;
54475 + else
54477 + constraint_route_resolution_sm_destroy (pSm);
54478 + return pCall;
54481 + switch (pCrArgs->rc)
54483 + case OUTPUT_LSP_SETUP_PENDING:
54484 + pSm->state = CONSTAINT_ROUTE_RESOLUTION_SM_ADAPTIVITY_STATE;
54485 + return NULL;
54486 + case OUTPUT_EGRESS:
54487 + case OUTPUT_LSP:
54488 + case OUTPUT_NEXT_HOP:
54489 + case OUTPUT_PATH:
54490 + event = CONSTRAINT_ROUTE_RESOLVED_EVENT;
54491 + break;
54492 + case OUTPUT_CAC_FAILED:
54493 + case OUTPUT_UNREACHABLE:
54494 + if ((pCspfRequest = CreateCspfRequest (pCrArgs->dest,
54495 + pCrArgs->SetupPriority,
54496 + pCrArgs->ExclColorMask,
54497 + pCrArgs->
54498 + InclAnyColorMask,
54499 + pCrArgs->InclColorMask,
54500 + pCrArgs->HopCount,
54501 + pCrArgs->BW,
54502 + pCrArgs->LinkBwNumber,
54503 + (LINK_BW *) pCrArgs->
54504 + pLinkBw,
54505 + pCrArgs->AvoidHopNumber,
54506 + pCrArgs->AvoidHopsArray,
54507 + pCrArgs->
54508 + ExcludeHopNumber,
54509 + pCrArgs->
54510 + ExcludeHopsArray, &Len,
54511 + &pMessage)) == NULL)
54513 + return NULL;
54515 + pCspfRequest->handle = pSm;
54516 + te_send_msg (pMessage, Len);
54517 + XFREE (MTYPE_TE, pMessage);
54518 + RegisterClient ((int) pSm->caller,
54519 + pCrArgs->PsbKey.Session.TunnelId,
54520 + pCrArgs->dest, pSm);
54521 + return NULL;
54522 + default:
54523 + zlog_err ("default case %s %d", __FILE__, __LINE__);
54524 + event = CONSTRAINT_ROUTE_RESOLVE_FAILED_EVENT;
54526 + if ((pCall =
54527 + sm_gen_sync_event_send (pSm->caller, event, pCrArgs)) == NULL)
54529 + zlog_err ("cannot send sycn event %s %d", __FILE__, __LINE__);
54531 + break;
54532 + case NEXT_HOP_DEST:
54533 + if (NextHopConstraintRouteResolution (pSm, pCrArgs) != E_OK)
54535 + zlog_info ("Next Hop constraint route resolution failed");
54536 + if ((pCall =
54537 + sm_gen_sync_event_send (pSm->caller, event,
54538 + pCrArgs)) == NULL)
54540 + zlog_err ("cannot send sycn event %s %d", __FILE__,
54541 + __LINE__);
54542 + constraint_route_resolution_sm_destroy (pSm);
54543 + return NULL;
54545 + else
54547 + constraint_route_resolution_sm_destroy (pSm);
54548 + return pCall;
54551 + switch (pCrArgs->rc)
54553 + case OUTPUT_EGRESS:
54554 + case OUTPUT_LSP:
54555 + case OUTPUT_NEXT_HOP:
54556 + case OUTPUT_PATH:
54557 + event = CONSTRAINT_ROUTE_RESOLVED_EVENT;
54558 + break;
54559 + case OUTPUT_CAC_FAILED:
54560 + case OUTPUT_UNREACHABLE:
54561 + event = CONSTRAINT_ROUTE_RESOLVE_FAILED_EVENT;
54562 + break;
54563 + default:
54564 + zlog_err ("default case %s %d", __FILE__, __LINE__);
54565 + event = CONSTRAINT_ROUTE_RESOLVE_FAILED_EVENT;
54567 + if ((pCall =
54568 + sm_gen_sync_event_send (pSm->caller, event, pCrArgs)) == NULL)
54570 + zlog_err ("cannot send sycn event %s %d", __FILE__, __LINE__);
54572 + break;
54573 + case UNKNOWN_DEST:
54574 + if ((pCspfRequest = CreateCspfRequest (pCrArgs->dest,
54575 + pCrArgs->SetupPriority,
54576 + pCrArgs->ExclColorMask,
54577 + pCrArgs->InclAnyColorMask,
54578 + pCrArgs->InclColorMask,
54579 + pCrArgs->HopCount,
54580 + pCrArgs->BW,
54581 + pCrArgs->LinkBwNumber,
54582 + (LINK_BW *) pCrArgs->pLinkBw,
54583 + pCrArgs->AvoidHopNumber,
54584 + pCrArgs->AvoidHopsArray,
54585 + pCrArgs->ExcludeHopNumber,
54586 + pCrArgs->ExcludeHopsArray,
54587 + &Len, &pMessage)) == NULL)
54589 + return NULL;
54591 + pCspfRequest->handle = pSm;
54592 + te_send_msg (pMessage, Len);
54593 + XFREE (MTYPE_TE, pMessage);
54594 + RegisterClient ((int) pSm->caller,
54595 + pCrArgs->PsbKey.Session.TunnelId,
54596 + pCrArgs->dest, pSm);
54597 + return NULL;
54598 + case LOCAL_IF_DEST:
54599 + pCrArgs->rc = OUTPUT_EGRESS;
54600 + if ((pCall = sm_gen_sync_event_send (pSm->caller,
54601 + CONSTRAINT_ROUTE_RESOLVED_EVENT,
54602 + pCrArgs)) == NULL)
54604 + zlog_err ("cannot send sycn event %s %d", __FILE__, __LINE__);
54606 + break;
54607 + default:
54608 + zlog_err ("default case %s %d", __FILE__, __LINE__);
54609 + if ((pCall = sm_gen_sync_event_send (pSm->caller,
54610 + CONSTRAINT_ROUTE_RESOLVE_FAILED_EVENT,
54611 + pCrArgs)) == NULL)
54613 + zlog_err ("cannot send sycn event %s %d", __FILE__, __LINE__);
54616 + break;
54617 + default:
54618 + zlog_err ("unexpected event %d %s %d",
54619 + sm_event->event, __FILE__, __LINE__);
54621 + constraint_route_resolution_sm_destroy (pSm);
54622 + return pCall;
54625 +static SM_CALL_T *
54626 +constraint_route_resolution_sm_dynamic_adaptivity (SM_T * pSm,
54627 + SM_EVENT_T * sm_event)
54629 + LSP_SM_REPLY *pLspSmReply = sm_event->data;
54630 + SM_CALL_T *pCall = NULL;
54631 + CONSTRAINT_ROUTE_RESOLUTION_SM_DATA *pCrSmData = pSm->data;
54632 + SM_EVENT_E event = CONSTRAINT_ROUTE_RESOLVE_FAILED_EVENT;
54633 + //TUNNEL_KEY_T tunnel_key;
54635 + switch (sm_event->event)
54637 + case INGRESS_LSP_OPERATION_COMPLETE_EVENT:
54638 + sm_gen_event_trace (sm_event->event);
54639 + pCrSmData->args->rc = OUTPUT_LSP;
54640 + pCrSmData->args->data.tunnel.Session.Dest = pLspSmReply->dest;
54641 + pCrSmData->args->data.tunnel.Session.TunnelId = pLspSmReply->tunnel_id;
54642 + pCrSmData->args->data.tunnel.Session.ExtTunelId = rdb_get_router_id ();
54643 + pCrSmData->args->OutNHop = pLspSmReply->dest;
54645 + zlog_info ("\nTUNNELED: Tunnels Dest %x tunnel id %x IfIndex %d",
54646 + pLspSmReply->dest, pLspSmReply->tunnel_id,
54647 + pCrSmData->args->OutIf);
54648 + break;
54649 + case INGRESS_LSP_OPERATION_FAILED_EVENT:
54650 + sm_gen_event_trace (sm_event->event);
54651 + pCrSmData->args->rc = OUTPUT_UNREACHABLE;
54652 + break;
54653 + default:
54654 + zlog_err ("\nunexpected event %d %s %d",
54655 + sm_event->event, __FILE__, __LINE__);
54657 + if ((pCall =
54658 + sm_gen_sync_event_send (pSm->caller, event, pCrSmData->args)) == NULL)
54660 + zlog_err ("\ncannot send sycn event %s %d", __FILE__, __LINE__);
54662 + constraint_route_resolution_sm_destroy (pSm);
54663 + return pCall;
54666 +static SM_CALL_T
54667 + *(*constraint_route_resolution_sm_event_handler
54668 + [CONSTRAINT_ROUTE_RESOLUTION_SM_MAX_STATE]) (SM_T * pSm,
54669 + SM_EVENT_T * sm_data) =
54671 +constraint_route_resolution_sm_empty_handler,
54672 + constraint_route_resolution_sm_init,
54673 + constraint_route_resolution_sm_dynamic_adaptivity};
54675 +SM_CALL_T *
54676 +constraint_route_resolution_sm_handler (SM_T * pSm, SM_EVENT_T * sm_data)
54678 + if (sm_data == NULL)
54680 + zlog_err ("\nfatal: sm_data is NULL %s %d", __FILE__, __LINE__);
54681 + return NULL;
54683 + zlog_info ("constraint_route_resolution_sm_handler. state %d", pSm->state);
54684 + if ((pSm->state < INIT_STATE)
54685 + || (pSm->state >= CONSTRAINT_ROUTE_RESOLUTION_SM_MAX_STATE))
54687 + zlog_err ("\nstate is invalid");
54688 + XFREE (MTYPE_TE, sm_data);
54689 + sm_gen_free (pSm);
54690 + return NULL;
54692 + return constraint_route_resolution_sm_event_handler[pSm->state] (pSm,
54693 + sm_data);
54696 +SM_CALL_T *
54697 +constraint_route_resolution_sm_invoke (SM_T * caller, void *data)
54699 + SM_T *pNewSm;
54700 + SM_CALL_T *pEvent;
54702 + pNewSm = sm_gen_alloc (caller, CONSTRAINT_ROUTE_RESOLUTION_SM);
54703 + if (pNewSm == NULL)
54705 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
54706 + return NULL;
54708 + if ((pEvent = sm_gen_sync_event_send (pNewSm,
54709 + CONSTRAINT_ROUTE_RESOLUTION_REQ_EVENT,
54710 + data)) == NULL)
54712 + zlog_err ("\ncan not invoke sm %s %d", __FILE__, __LINE__);
54714 + return pEvent;
54717 +static RSVP_TUNNEL_PROPERTIES *
54718 +FindTunnelByPath (TRUNK_ENTRY * pTrunkEntry, PATH * pPath)
54720 + RSVP_TUNNEL_PROPERTIES *pTunnel = pTrunkEntry->Lsps;
54721 + while (pTunnel != NULL)
54723 + RSVP_LSP_PROPERTIES *pRsvpLsp;
54724 + if ((pRsvpLsp = GetWorkingRsvpLsp (pTunnel)) != NULL)
54726 + if (PathsEqual (pPath->u.er_hops_l_list,
54727 + pRsvpLsp->forw_info.path.pErHopsList,
54728 + (pPath->PathProperties.PathHopCount >=
54729 + (pRsvpLsp->forw_info.path.HopCount - 1)) ?
54730 + pRsvpLsp->forw_info.path.HopCount : pPath->
54731 + PathProperties.PathHopCount) == TRUE)
54733 + return pTunnel;
54736 + pTunnel = pTunnel->next;
54738 + return NULL;
54741 +static BOOL
54742 +SummaryAdmissionControl (SUMMARY_PROPERTIES * pSummaryProperties,
54743 + CONSTRAINT_ROUTE_RESOLUTION_ARGS * args)
54745 + if (pSummaryProperties->SummaryMaxLspBW < args->BW)
54747 + zlog_info ("\nSummaryMaxLspBW#%x < BW#%x",
54748 + pSummaryProperties->SummaryMaxLspBW, args->BW);
54749 + return FALSE;
54751 + if (pSummaryProperties->SummaryMaxReservableBW < args->BW)
54753 + zlog_info ("\nSummaryMaxReservableBW#%x < BW#%x",
54754 + pSummaryProperties->SummaryMaxReservableBW, args->BW);
54755 + return FALSE;
54757 + /*
54758 + if(pSummaryProperties->ColorMask & args->ExclColorMask)
54760 + zlog_info("\nColors to be excluded#%x exist#%x",
54761 + args->ExclColorMask,
54762 + pPathProperties->PathColorMask);
54763 + return FALSE;
54765 + if((pSummaryProperties->ColorMask & args->InclColorMask) != args->InclColorMask)
54767 + zlog_info("\nColors to be included#%x don't exist#%x",
54768 + args->InclColorMask,
54769 + pPathProperties->PathColorMask);
54770 + return FALSE;
54772 + if(pSummaryProperties->HopCount > args->HopCount)
54774 + zlog_info("\nHop count#%x is higher#%x",args->HopCount,pPathProperties->PathHopCount);
54775 + return FALSE;
54777 + */
54778 + return TRUE;
54781 +static BOOL
54782 +SummaryTieBreak (SUMMARY_PROPERTIES * pLeftSummary, PATH * pLeftPath,
54783 + SUMMARY_PROPERTIES * pRightSummary, PATH * pRightPath,
54784 + uns8 Priority)
54786 + float LeftMin, RightMin;
54787 + if ((pLeftSummary->SummaryCost + pLeftPath->PathProperties.PathCost) <
54788 + (pRightSummary->SummaryCost + pRightPath->PathProperties.PathCost))
54790 + return FALSE;
54793 + if ((pLeftSummary->SummaryCost + pLeftPath->PathProperties.PathCost) >
54794 + (pRightSummary->SummaryCost + pRightPath->PathProperties.PathCost))
54796 + return TRUE;
54799 + LeftMin =
54800 + (pLeftSummary->SummaryReservableBW[Priority] <
54801 + pLeftPath->PathProperties.PathReservableBW[Priority]) ? pLeftSummary->
54802 + SummaryReservableBW[Priority] : pLeftPath->PathProperties.
54803 + PathReservableBW[Priority];
54805 + RightMin =
54806 + (pRightSummary->SummaryReservableBW[Priority] <
54807 + pRightPath->PathProperties.PathReservableBW[Priority]) ? pRightSummary->
54808 + SummaryReservableBW[Priority] : pRightPath->PathProperties.
54809 + PathReservableBW[Priority];
54811 + if (LeftMin > RightMin)
54813 + return FALSE;
54816 + if (LeftMin < RightMin)
54818 + return TRUE;
54821 + LeftMin =
54822 + (pLeftSummary->SummaryMaxLspBW <
54823 + pLeftPath->PathProperties.PathMaxLspBW) ? pLeftSummary->
54824 + SummaryMaxLspBW : pLeftPath->PathProperties.PathMaxLspBW;
54826 + RightMin =
54827 + (pRightSummary->SummaryMaxLspBW <
54828 + pRightPath->PathProperties.PathMaxLspBW) ? pRightSummary->
54829 + SummaryMaxLspBW : pRightPath->PathProperties.PathMaxLspBW;
54830 + if (LeftMin > RightMin)
54832 + return FALSE;
54834 + if (LeftMin < RightMin)
54836 + return TRUE;
54838 + return FALSE;
54841 +static int
54842 +SelectAreaBorder (SM_T * pSm,
54843 + ABRS_L_LIST * pAbrs,
54844 + CONSTRAINT_ROUTE_RESOLUTION_ARGS * args,
54845 + ABR ** ppAbr, PATH ** ppPath)
54847 + PATH_L_LIST *pPathList = NULL;
54848 + PATH *pPath, *pSelectedPath = NULL;
54849 + ABR *pSelectedAbr = NULL;
54850 + zlog_info ("\ninside of Select AreaBorder...");
54851 + while (pAbrs != NULL)
54853 + SUMMARY_PROPERTIES *pProperties = pAbrs->Abr->SummaryProperties;
54854 + int NumberOfSummaries = pAbrs->Abr->NumberOfSummaries, i;
54855 + zlog_info ("\n#");
54856 + for (i = 0; i < NumberOfSummaries; i++)
54858 + zlog_info ("\n##");
54859 + if (pProperties->SummaryPathType == PSC_PATH)
54861 + if (SummaryAdmissionControl (pProperties, args) == TRUE)
54863 + if (IsDestinationIntraArea
54864 + (pAbrs->Abr->AbrIpAddr, &pPathList) != E_OK)
54866 + zlog_err
54867 + ("\nsome error in IsDestinationIntraArea %s %d ...",
54868 + __FILE__, __LINE__);
54869 + return E_ERR;
54871 + else
54873 + pPath = NULL;
54874 + if (SelectPath (pPathList, args, &pPath) != E_OK)
54876 + pPath = NULL;
54878 + else if ((pSelectedPath != NULL)
54879 + && (pSelectedAbr != NULL))
54881 + if (SummaryTieBreak
54882 + (pSelectedAbr->SummaryProperties, pSelectedPath,
54883 + pProperties, pPath,
54884 + args->SetupPriority) == TRUE)
54886 + pSelectedAbr = pAbrs->Abr;
54887 + pSelectedPath = pPath;
54890 + else
54892 + pSelectedAbr = pAbrs->Abr;
54893 + pSelectedPath = pPath;
54898 + else
54900 + zlog_err ("\ntype %x is not supported",
54901 + pProperties->SummaryPathType);
54903 + pProperties++;
54905 + pAbrs = pAbrs->next;
54907 + *ppAbr = pSelectedAbr;
54908 + *ppPath = pSelectedPath;
54909 + return E_OK;
54912 +static BOOL
54913 +PathAdmissionControl (PATH * pPath, CONSTRAINT_ROUTE_RESOLUTION_ARGS * args)
54915 + int i, j;
54916 + ER_HOP_L_LIST *er_hop_l_list;
54917 + PATH_PROPERTIES *pPathProperties = &pPath->PathProperties;
54918 + if (pPathProperties->PathMaxLspBW < args->BW)
54920 + zlog_info ("MaxLspBW#%f < BW#%f", pPathProperties->PathMaxLspBW,
54921 + args->BW);
54922 + return FALSE;
54924 + if (pPathProperties->PathMaxReservableBW < args->BW)
54926 + zlog_info ("MaxReservableBW#%f < BW#%f",
54927 + pPathProperties->PathMaxReservableBW, args->BW);
54928 + return FALSE;
54930 + if (pPathProperties->PathReservableBW[args->HoldPriority] < args->BW)
54932 + zlog_info ("ReservableBW#%f < BW#%f",
54933 + pPathProperties->PathReservableBW[args->HoldPriority],
54934 + args->BW);
54935 + return FALSE;
54937 + if (pPathProperties->PathColorMask & args->ExclColorMask)
54939 + zlog_info ("nColors to be excluded#%x exist#%x",
54940 + args->ExclColorMask, pPathProperties->PathColorMask);
54941 + return FALSE;
54943 + if ((args->InclAnyColorMask)
54944 + && ((pPathProperties->PathColorMask & args->InclAnyColorMask) == 0))
54946 + return FALSE;
54948 + if ((args->InclColorMask)
54949 + &&
54950 + (((pPathProperties->PathColorMask & args->InclColorMask) ^ args->
54951 + InclColorMask) != 0))
54953 + return FALSE;
54955 + if ((args->HopCount != 0) &&
54956 + (pPathProperties->PathHopCount > args->HopCount))
54958 + zlog_info ("Hop count#%x is higher#%x", args->HopCount,
54959 + pPathProperties->PathHopCount);
54960 + return FALSE;
54962 + for (er_hop_l_list = pPath->u.er_hops_l_list, i = 0;
54963 + i < (pPathProperties->PathHopCount) && (er_hop_l_list != NULL);
54964 + i++, er_hop_l_list = er_hop_l_list->next)
54966 + IPV4_ADDR router_id = er_hop_l_list->er_hop->local_ip;
54967 + rdb_remote_link_router_id_get (er_hop_l_list->er_hop->local_ip,
54968 + &router_id);
54969 + for (j = 0; j < args->ExcludeHopNumber; j++)
54971 + if (args->ExcludeHopsArray[j] == router_id)
54973 + return FALSE;
54977 + return TRUE;
54980 +static uns32
54981 +GetSharedHopsNumber (PATH * pPath, CONSTRAINT_ROUTE_RESOLUTION_ARGS * args)
54983 + uns32 SharedHopsNumber = 0, i;
54984 + for (i = 0; i < args->AvoidHopNumber; i++)
54986 + ER_HOP_L_LIST *pErHopsLList = pPath->u.er_hops_l_list;
54987 + while (pErHopsLList != NULL)
54989 + IPV4_ADDR router_id;
54990 + /* zlog_info("\nLeft ER HOP %x Right ER HOP %x",
54991 + pErHopsLList->er_hop->local_ip,
54992 + args->ExcludeHopsArray[i]); */
54993 + if (rdb_remote_link_router_id_get
54994 + (pErHopsLList->er_hop->remote_ip, &router_id) == E_OK)
54996 + if (router_id == args->AvoidHopsArray[i])
54998 + SharedHopsNumber++;
55001 + else
55003 + SharedHopsNumber++;
55005 + pErHopsLList = pErHopsLList->next;
55008 + return SharedHopsNumber;
55011 +static BOOL
55012 +PathTieBreak (PATH * pLeftPath,
55013 + PATH * pRigthPath,
55014 + CONSTRAINT_ROUTE_RESOLUTION_ARGS * args,
55015 + uns32 * CurrentSharedHopsNumber)
55017 + uns32 SharedHopsNumber = 0;
55018 + PATH_PROPERTIES *pLeftPathProperties =
55019 + &pLeftPath->PathProperties, *pRightPathProperties =
55020 + &pRigthPath->PathProperties;
55021 + if ((SharedHopsNumber =
55022 + GetSharedHopsNumber (pRigthPath, args)) < *CurrentSharedHopsNumber)
55024 + zlog_info ("Tie break by shared hops");
55025 + *CurrentSharedHopsNumber = SharedHopsNumber;
55026 + return TRUE;
55028 + else if (SharedHopsNumber > *CurrentSharedHopsNumber)
55030 + return FALSE;
55032 + /* if(args->BwPolicy == LEAST_FILL)
55035 + else if(args->BwPolicy == MOST_FILL)
55038 + else
55041 + */
55042 + return RightPathCheaper (pLeftPathProperties, pRightPathProperties,
55043 + args->SetupPriority);
55046 +int
55047 +SelectPath (PATH_L_LIST * pPaths,
55048 + CONSTRAINT_ROUTE_RESOLUTION_ARGS * args, PATH ** ppPath)
55050 + uns32 OutIf;
55051 + TE_LINK_L_LIST *pTeLinks = NULL;
55052 + uns32 SharedHopsNumber = 0;
55053 + IPV4_ADDR router_id;
55055 + while (pPaths != NULL)
55057 + zlog_info ("\n...");
55058 + if (PathAdmissionControl (pPaths->pPath, args) == TRUE)
55060 + zlog_info ("looking for first ER hop %x...",
55061 + pPaths->pPath->u.er_hops_l_list->er_hop->remote_ip);
55063 + if (rdb_remote_link_router_id_get
55064 + (pPaths->pPath->u.er_hops_l_list->er_hop->remote_ip,
55065 + &router_id) != E_OK)
55067 + router_id = pPaths->pPath->u.er_hops_l_list->er_hop->remote_ip;
55069 + if (IsDestinationNextHop (router_id, &pTeLinks) != E_OK)
55071 + zlog_err ("some error in IsDestinationNextHop %s %d ...",
55072 + __FILE__, __LINE__);
55073 + return E_ERR;
55075 + if (pTeLinks != NULL)
55077 + zlog_info ("looking for Out IF...");
55078 + if (SelectOutIf (pTeLinks, &OutIf, args, FALSE) != E_OK)
55080 + zlog_err ("some error in SelectOutIf %s %d ...", __FILE__,
55081 + __LINE__);
55082 + return E_ERR;
55084 + else if (OutIf != 0xFFFFFFFF)
55086 + if (*ppPath != NULL)
55088 + zlog_info ("Second matching path %x %x %x %x...",
55089 + SharedHopsNumber, *ppPath, pPaths->pPath,
55090 + args);
55091 + if (PathTieBreak
55092 + (*ppPath, pPaths->pPath, args,
55093 + &SharedHopsNumber) == TRUE)
55095 + zlog_info (" Selected %x.", SharedHopsNumber);
55096 + *ppPath = pPaths->pPath;
55098 + zlog_info ("After PathTieBreak...");
55100 + else
55102 + zlog_info ("First matching path...");
55103 + SharedHopsNumber =
55104 + GetSharedHopsNumber (pPaths->pPath, args);
55105 + *ppPath = pPaths->pPath;
55109 + else
55111 + zlog_info ("there is no TE link...");
55114 + pPaths = pPaths->next;
55116 + return E_OK;
55119 +static BOOL
55120 +LinkAdmissionControl (TE_LINK_PROPERTIES * pTeLinkProperties,
55121 + COMPONENT_LINK * pComponentLink,
55122 + CONSTRAINT_ROUTE_RESOLUTION_ARGS * args)
55124 + int reason = 0;
55125 + if (pTeLinkProperties->MaxLspBW < args->BW)
55127 + reason = 1;
55129 + if (pTeLinkProperties->MaxReservableBW < args->BW)
55131 + reason = 2;
55133 + if (pTeLinkProperties->ReservableBW[args->HoldPriority] < args->BW)
55135 + zlog_info ("HoldPrio %x ResBw %d BW %d", args->HoldPriority,
55136 + pTeLinkProperties->ReservableBW[args->HoldPriority],
55137 + args->BW);
55138 + reason = 3;
55140 + if ((pTeLinkProperties->color_mask & args->ExclColorMask) != 0)
55142 + reason = 4;
55144 + if ((args->InclAnyColorMask)
55145 + && ((pTeLinkProperties->color_mask & args->InclAnyColorMask) == 0))
55147 + reason = 5;
55149 + if ((args->InclColorMask)
55150 + &&
55151 + (((pTeLinkProperties->color_mask & args->InclColorMask) ^ args->
55152 + InclColorMask) != 0))
55154 + reason = 6;
55156 + if (reason)
55157 + zlog_info ("LinkAdmissionControl failed. Reason %d", reason);
55158 + return (reason) ? FALSE : TRUE;
55161 +int
55162 +SelectOutIf (TE_LINK_L_LIST * pTeLinks,
55163 + uns32 * OutIf,
55164 + CONSTRAINT_ROUTE_RESOLUTION_ARGS * args, BOOL PerformAllocation)
55166 + COMPONENT_LINK *pComponentLink, *pSelectedComponentLink = NULL;
55167 + TE_LINK *pSelectedTeLink = NULL;
55168 + float ActuallyRequired, LeastActuallyRequired = 0xFFFFFFFF;
55169 + /*FIXME*/ PSB_KEY * owner = &args->PsbKey;
55170 + float BW = args->BW;
55171 + uns8 PreemptedPriority = args->HoldPriority, MostPreemptedPriority = 0;
55172 + ActuallyRequired = BW;
55173 + *OutIf = 0xFFFFFFFF;
55175 + while (pTeLinks != NULL)
55177 + zlog_info ("TE link %x ActuallyRequired %f...",
55178 + pTeLinks->te_link->te_link_id, BW);
55179 + pComponentLink = pTeLinks->te_link->component_links;
55180 + while (pComponentLink != NULL)
55182 + if (LinkAdmissionControl
55183 + (&pTeLinks->te_link->te_link_properties, pComponentLink,
55184 + args) == FALSE)
55186 + pComponentLink = pComponentLink->next;
55187 + continue;
55189 + zlog_info ("trying to calculate BW to be allocated actually...");
55190 + if (CalcActualAlloc (owner,
55191 + pTeLinks->te_link->te_link_id,
55192 + pComponentLink,
55193 + &ActuallyRequired,
55194 + args->SetupPriority,
55195 + args->HoldPriority,
55196 + &PreemptedPriority) == E_OK)
55198 + zlog_info ("Actual BW to be allocated %f PreemptedPriority %x",
55199 + ActuallyRequired, PreemptedPriority);
55200 + if (PerformAllocation == TRUE)
55202 + if ((ActuallyRequired < LeastActuallyRequired) &&
55203 + (PreemptedPriority >= MostPreemptedPriority))
55205 + zlog_info
55206 + ("##Actual BW to be allocated %f PreemptedPriority %x",
55207 + ActuallyRequired, PreemptedPriority);
55208 + LeastActuallyRequired = ActuallyRequired;
55209 + MostPreemptedPriority = PreemptedPriority;
55210 + pSelectedComponentLink = pComponentLink;
55211 + pSelectedTeLink = pTeLinks->te_link;
55214 + else
55216 + *OutIf = pComponentLink->oifIndex;
55217 + return E_OK;
55220 + pComponentLink = pComponentLink->next;
55222 + pTeLinks = pTeLinks->next;
55224 + if (PerformAllocation == TRUE)
55226 + if ((pSelectedComponentLink != NULL) && (pSelectedTeLink != NULL))
55228 + zlog_info ("trying to perform allocation...");
55229 + if (DoPreBwAllocation (owner,
55230 + pSelectedTeLink->te_link_id,
55231 + pSelectedComponentLink,
55232 + ActuallyRequired,
55233 + args->HoldPriority) != E_OK)
55235 + zlog_err ("something wrong %s %d", __FILE__, __LINE__);
55237 + else
55239 + zlog_info ("Success!!!");
55240 + *OutIf = pSelectedComponentLink->oifIndex;
55243 + else
55245 + *OutIf = 0xFFFFFFFF;
55248 + zlog_info ("inside of %x...", *OutIf);
55249 + return E_OK;
55252 +static uns32
55253 +DetermineDestinationType (SM_T * pSm,
55254 + CONSTRAINT_ROUTE_RESOLUTION_ARGS * args,
55255 + DESTINATION_TYPE_E * type)
55257 + TE_LINK_L_LIST *pTeLinks = NULL;
55258 + PATH_L_LIST *pPaths = NULL;
55259 + ABRS_L_LIST *pAbrs = NULL;
55260 + uns32 OutIf = 0xFFFFFFFF;
55261 + IPV4_ADDR router_id;
55263 + zlog_info ("Am I the destination? %x", args->dest);
55264 + if (AmIDestination (args->dest, &OutIf) != E_OK)
55266 + zlog_err ("some error in AmIDestination %s %d...", __FILE__, __LINE__);
55267 + return E_ERR;
55270 + if ((OutIf == 0) || (OutIf != 0xFFFFFFFF))
55272 + zlog_info ("\nYes");
55273 + *type = LOCAL_IF_DEST;
55274 + return E_OK;
55277 + zlog_info ("Is destination %x a Next Hop?", args->dest);
55279 + if (rdb_remote_link_router_id_get (args->dest, &router_id) != E_OK)
55281 + router_id = args->dest;
55284 + if (IsDestinationNextHop (router_id, &pTeLinks) != E_OK)
55286 + zlog_err ("some error in IsDestinationNextHop %s %d...", __FILE__,
55287 + __LINE__);
55288 + return E_ERR;
55290 + if (pTeLinks == NULL)
55292 + zlog_info ("Is destination intra-area?");
55293 + if (IsDestinationIntraArea (args->dest, &pPaths) != E_OK)
55295 + zlog_err ("some error in IsDestinationIntraArea %s %d...", __FILE__,
55296 + __LINE__);
55297 + return E_ERR;
55299 + if (pPaths == NULL)
55301 + zlog_info ("Is destination AS border?");
55302 + if (IsDestinationASBorder (args->dest, &pAbrs) != E_OK)
55304 + zlog_err ("some error in IsDestinationASBorder %s %d...",
55305 + __FILE__, __LINE__);
55306 + return E_ERR;
55308 + if (pAbrs == NULL)
55310 + zlog_info
55311 + ("Destination seems to be nor Next Hop nor Area Border nor AS Border...");
55312 + *type = UNKNOWN_DEST;
55314 + else
55316 + *type = OUT_OF_AREA_DEST;
55319 + else
55321 + *type = INTRA_AREA_DEST;
55324 + else
55326 + *type = NEXT_HOP_DEST;
55328 + return E_OK;
55331 +static uns32
55332 +NextHopConstraintRouteResolution (SM_T * pSm,
55333 + CONSTRAINT_ROUTE_RESOLUTION_ARGS * args)
55335 + TE_LINK_L_LIST *pTeLinks = NULL;
55336 + IPV4_ADDR router_id;
55338 + if (rdb_remote_link_router_id_get (args->dest, &router_id) != E_OK)
55340 + router_id = args->dest;
55343 + if (IsDestinationNextHop (router_id, &pTeLinks) != E_OK)
55345 + zlog_err ("some error in IsDestinationNextHop %s %d ...", __FILE__,
55346 + __LINE__);
55347 + return E_ERR;
55349 + if (pTeLinks == NULL)
55351 + zlog_err ("unexpected error: pTeLink == NULL %s %d", __FILE__,
55352 + __LINE__);
55353 + return E_ERR;
55355 + if (SelectOutIf (pTeLinks, &args->OutIf, args, TRUE) != E_OK)
55357 + zlog_err ("error in SelectOutIf %s %d", __FILE__, __LINE__);
55358 + return E_ERR;
55360 + if (args->OutIf == 0xFFFFFFFF)
55362 + args->rc = OUTPUT_CAC_FAILED;
55364 + else
55366 + args->OutNHop = args->dest;
55367 + args->rc = OUTPUT_NEXT_HOP;
55369 + return E_OK;
55372 +static BOOL
55373 +OwnTunnel (IPV4_ADDR addr)
55375 + return (addr == rdb_get_router_id ());
55378 +static uns32
55379 +IntraAreaConstraintRouteResolution (SM_T * pSm,
55380 + CONSTRAINT_ROUTE_RESOLUTION_ARGS * args)
55382 + PATH_L_LIST *pPaths = NULL;
55383 + PATH *pSelectedPath = NULL;
55384 + TE_LINK_L_LIST *pTeLinks = NULL;
55385 + PSB_KEY PsbKey;
55386 + IPV4_ADDR *pIpAddrArray, router_id;
55388 + if (IsDestinationIntraArea (args->dest, &pPaths) != E_OK)
55390 + zlog_err ("some error in IsDestinationIntraArea %s %d ...", __FILE__,
55391 + __LINE__);
55392 + return E_ERR;
55394 + if (pPaths != NULL)
55396 + if (SelectPath (pPaths, args, &pSelectedPath) != E_OK)
55398 + zlog_err ("some error in SelectPath %s %d ...", __FILE__, __LINE__);
55399 + return E_ERR;
55401 + if (pSelectedPath != NULL)
55403 + ER_HOP_L_LIST *pErHopList = pSelectedPath->u.er_hops_l_list;
55404 + int i;
55406 + if ((TunnelsAutoSetup == TRUE) &&
55407 + (!((args->dest == args->PsbKey.Session.Dest) &&
55408 + (OwnTunnel (args->PsbKey.Session.ExtTunelId)))))
55410 + TRUNK_KEY trunk_key;
55411 + TRUNK_ENTRY *pTrunkEntry;
55412 + RSVP_TUNNEL_PROPERTIES *pTunnel;
55413 + INGRESS_API *pOpenLspParams;
55414 + SM_CALL_T *pCall;
55416 + memset (&trunk_key, 0, sizeof (TRUNK_KEY));
55417 + trunk_key.Dest = args->dest;
55418 + if ((pTrunkEntry = GetTunnelsTrunk (&trunk_key)) == NULL)
55420 + if ((pTrunkEntry = NewTunnelsTrunk (&trunk_key)) == NULL)
55422 + zlog_err ("cannot create tunnels trunk %s %d", __FILE__,
55423 + __LINE__);
55424 + return E_ERR;
55427 + pTunnel = pTrunkEntry->Lsps;
55428 + if ((pOpenLspParams = CreateRequest2Signalling (pSelectedPath->destination, 0, /* Filled below */
55429 + 0, NULL, /* Filled below */
55430 + 0, /* Filled below */
55431 + 4, 4, /* Default */
55432 + LOCAL_PROTECTION_DESIRED,
55433 + 0, 0,
55435 + /* Default for now */
55436 + )) == NULL)
55438 + zlog_err ("cannot create request %s %d", __FILE__,
55439 + __LINE__);
55440 + return E_ERR;
55443 + pOpenLspParams->HopNum =
55444 + pSelectedPath->PathProperties.PathHopCount * 2;
55446 + for (i = 0, pErHopList = pSelectedPath->u.er_hops_l_list;
55447 + pErHopList != NULL; pErHopList = pErHopList->next)
55449 + if (i)
55451 + pOpenLspParams->Path[i++].IpAddr =
55452 + pErHopList->er_hop->local_ip;
55454 + pOpenLspParams->Path[i++].IpAddr =
55455 + pErHopList->er_hop->remote_ip;
55457 + args->OutNHop = pOpenLspParams->Path[0].IpAddr;
55458 + args->tunneled = TRUE;
55459 + if ((pTunnel =
55460 + FindTunnelByPath (pTrunkEntry, pSelectedPath)) != NULL)
55462 + if (CurrentPathHasAvBw (pTunnel, args->BW) != NULL)
55464 + pOpenLspParams->TunnelId = pTunnel->TunnelId;
55465 + pOpenLspParams->BW = pTunnel->RequiredBW + args->BW;
55467 + else
55469 + memset (&PsbKey, 0, sizeof (PSB_KEY));
55470 + PsbKey.Session.Dest = pSelectedPath->destination;
55471 + pOpenLspParams->TunnelId = NewTunnelId (&PsbKey);
55472 + pOpenLspParams->BW = args->BW;
55475 + else
55477 + memset (&PsbKey, 0, sizeof (PSB_KEY));
55478 + PsbKey.Session.Dest = pSelectedPath->destination;
55479 + pOpenLspParams->TunnelId = NewTunnelId (&PsbKey);
55480 + pOpenLspParams->BW = args->BW;
55482 + if ((pCall =
55483 + lsp_sm_sync_invoke (pSm, pOpenLspParams,
55484 + INGRESS_LSP_REQUEST_EVENT)) == NULL)
55486 + zlog_err ("cannot invoke lsp sm %s %d", __FILE__, __LINE__);
55487 + return E_ERR;
55489 + else
55490 + sm_call (pCall);
55491 + args->rc = OUTPUT_LSP_SETUP_PENDING;
55492 + return E_OK;
55495 + if (rdb_remote_link_router_id_get
55496 + (pSelectedPath->u.er_hops_l_list->er_hop->remote_ip,
55497 + &router_id) != E_OK)
55499 + router_id = pSelectedPath->u.er_hops_l_list->er_hop->remote_ip;
55502 + if (IsDestinationNextHop (router_id, &pTeLinks) != E_OK)
55504 + zlog_err ("some error in IsDestinationNextHop %s %d ...",
55505 + __FILE__, __LINE__);
55506 + return E_ERR;
55508 + if (pTeLinks == NULL)
55510 + zlog_err ("unexpected error: pTeLink == NULL %s %d", __FILE__,
55511 + __LINE__);
55512 + return E_ERR;
55515 + args->tunneled = FALSE;
55517 + if (SelectOutIf (pTeLinks, &args->OutIf, args, TRUE) != E_OK)
55519 + zlog_err ("an error in SelectOutIf %s %d", __FILE__, __LINE__);
55520 + return E_ERR;
55522 + if (args->OutIf == 0xFFFFFFFF)
55524 + args->rc = OUTPUT_CAC_FAILED;
55526 + else
55528 + if ((pIpAddrArray =
55529 + (IPV4_ADDR *) XMALLOC (MTYPE_TE,
55530 + sizeof (IPV4_ADDR) *
55531 + (pSelectedPath->PathProperties.
55532 + PathHopCount * 2))) == NULL)
55534 + zlog_err ("mem_alloc failed %s %d", __FILE__, __LINE__);
55535 + args->rc = OUTPUT_CAC_FAILED;
55536 + return E_ERR;
55538 + for (i = 0, pErHopList = pSelectedPath->u.er_hops_l_list;
55539 + pErHopList; pErHopList = pErHopList->next)
55541 + if (i)
55542 + pIpAddrArray[i++] = pErHopList->er_hop->local_ip;
55543 + pIpAddrArray[i++] = pErHopList->er_hop->remote_ip;
55545 + pIpAddrArray[i] = pSelectedPath->destination;
55546 + args->OutNHop = pIpAddrArray[0];
55547 + args->data.path.ErHopNumber =
55548 + pSelectedPath->PathProperties.PathHopCount * 2;
55549 + args->data.path.pErHop = pIpAddrArray;
55550 + zlog_info ("\nConsRouteResolution ErHopNumber %d pErHop %x",
55551 + args->data.path.ErHopNumber, args->data.path.pErHop);
55552 + args->rc = OUTPUT_PATH;
55555 + else
55557 + args->rc = OUTPUT_CAC_FAILED;
55560 + return E_OK;
55563 +static uns32
55564 +InterAreaConstraintRouteResolution (SM_T * pSm,
55565 + CONSTRAINT_ROUTE_RESOLUTION_ARGS * args)
55567 + PATH *pPath = NULL;
55568 + ABRS_L_LIST *pAbrs = NULL;
55569 + TE_LINK_L_LIST *pTeLinks = NULL;
55570 + ABR *pAbr = NULL;
55571 + RSVP_TUNNEL_PROPERTIES *pTunnel = NULL;
55572 + IPV4_ADDR *pErHopArray, router_id;
55573 + INGRESS_API *pOpenLspParams;
55574 + PSB_KEY PsbKey;
55575 + SM_CALL_T *pCall;
55576 + ER_HOP_L_LIST *pErHopList;
55577 + int i;
55579 + /* select the existing tunnels */
55580 + if (IsDestinationASBorder (args->dest, &pAbrs) != E_OK)
55582 + zlog_err ("\nsome error in IsDestinationASBorder %s %d...", __FILE__,
55583 + __LINE__);
55584 + return E_ERR;
55586 + if (SelectAreaBorder (pSm, pAbrs, args, &pAbr, &pPath) != E_OK)
55588 + zlog_err ("\nSelectAreaBorders failed...");
55589 + return E_ERR;
55591 + if ((pAbr == NULL) || (pPath == NULL))
55593 + zlog_info ("\nRR failed %s %d", __FILE__, __LINE__);
55594 + args->rc = OUTPUT_UNREACHABLE;
55595 + return E_ERR;
55597 + pErHopList = pPath->u.er_hops_l_list;
55599 + if ((TunnelsAutoSetup == TRUE) &&
55600 + (!((pAbr->AbrIpAddr == args->PsbKey.Session.Dest) &&
55601 + (OwnTunnel (args->PsbKey.Session.ExtTunelId)))))
55603 + TRUNK_ENTRY *pTrunkEntry;
55604 + TRUNK_KEY trunk_key;
55606 + memset (&trunk_key, 0, sizeof (TRUNK_KEY));
55607 + trunk_key.Dest = pAbr->AbrIpAddr;
55608 + if ((pTrunkEntry = GetTunnelsTrunk (&trunk_key)) == NULL)
55610 + if ((pTrunkEntry = NewTunnelsTrunk (&trunk_key)) == NULL)
55612 + zlog_err ("\ncannot create new tunnels trunk %s %d", __FILE__,
55613 + __LINE__);
55614 + return E_ERR;
55617 + if ((pOpenLspParams = CreateRequest2Signalling (pAbr->AbrIpAddr, 0, /* Filled below */
55618 + 0, NULL, /* Filled below */
55619 + 0, /* Filled below */
55620 + 4, 4, /* Default for now */
55621 + LOCAL_PROTECTION_DESIRED,
55622 + 0, 0,
55623 + 0 /* Default for now */
55624 + )) == NULL)
55626 + zlog_info ("\nmalloc failed %s %d", __FILE__, __LINE__);
55627 + return E_ERR;
55629 + pOpenLspParams->Egress = pAbr->AbrIpAddr;
55630 + args->tunneled = TRUE;
55631 + if ((pTunnel = FindTunnelByPath (pTrunkEntry, pPath)) != NULL)
55633 + if (CurrentPathHasAvBw (pTunnel, args->BW) != NULL)
55635 + pOpenLspParams->TunnelId = pTunnel->TunnelId;
55636 + pOpenLspParams->BW = pTunnel->RequiredBW + args->BW;
55638 + else
55640 + memset (&PsbKey, 0, sizeof (PSB_KEY));
55641 + PsbKey.Session.Dest = pAbr->AbrIpAddr;
55642 + pOpenLspParams->TunnelId = NewTunnelId (&PsbKey);
55643 + pOpenLspParams->BW = args->BW;
55646 + else
55648 + memset (&PsbKey, 0, sizeof (PSB_KEY));
55649 + PsbKey.Session.Dest = pAbr->AbrIpAddr;
55650 + pOpenLspParams->TunnelId = NewTunnelId (&PsbKey);
55651 + pOpenLspParams->BW = args->BW;
55653 + if ((pCall =
55654 + lsp_sm_sync_invoke (pSm, pOpenLspParams,
55655 + INGRESS_LSP_REQUEST_EVENT)) == NULL)
55657 + zlog_err ("\ncannot invoke lsp sm %s %d", __FILE__, __LINE__);
55658 + return E_ERR;
55660 + else
55661 + sm_call (pCall);
55662 + args->rc = OUTPUT_LSP_SETUP_PENDING;
55663 + return E_OK;
55665 + if (rdb_remote_link_router_id_get
55666 + (pPath->u.er_hops_l_list->er_hop->remote_ip, &router_id) != E_OK)
55668 + router_id = pPath->u.er_hops_l_list->er_hop->remote_ip;
55670 + if (IsDestinationNextHop (router_id, &pTeLinks) != E_OK)
55672 + zlog_err ("\nsome error in IsDestinationNextHop %s %d ...", __FILE__,
55673 + __LINE__);
55674 + return E_ERR;
55676 + if (pTeLinks == NULL)
55678 + zlog_err ("\nunexpected error: pTeLink == NULL %s %d", __FILE__,
55679 + __LINE__);
55680 + return E_ERR;
55682 + if ((pErHopArray =
55683 + (IPV4_ADDR *) XMALLOC (MTYPE_TE,
55684 + sizeof (IPV4_ADDR) *
55685 + (pPath->PathProperties.PathHopCount * 2))) ==
55686 + NULL)
55688 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
55689 + return E_ERR;
55691 + args->tunneled = FALSE;
55692 + args->data.path.ErHopNumber = pPath->PathProperties.PathHopCount * 2;
55694 + for (i = 0, pErHopList = pPath->u.er_hops_l_list;
55695 + pErHopList != NULL; pErHopList = pErHopList->next)
55697 + if (i)
55699 + *(pErHopArray + i) = pErHopList->er_hop->local_ip;
55700 + i++;
55702 + *(pErHopArray + i) = pErHopList->er_hop->remote_ip;
55703 + i++;
55706 + if (SelectOutIf (pTeLinks, &args->OutIf, args, TRUE) != E_OK)
55708 + zlog_err ("\nerror in SelectOutIf %s %d", __FILE__, __LINE__);
55709 + return E_ERR;
55711 + args->data.path.pErHop = pErHopArray;
55712 + args->OutNHop = pPath->u.er_hops_l_list->er_hop->remote_ip;
55713 + args->rc = OUTPUT_PATH;
55715 + return E_OK;
55718 +static BOOL
55719 +TunnelsTunnel2BeModified (CONSTRAINT_ROUTE_RESOLUTION_ARGS * args, SM_T * pSm)
55721 + RSVP_TUNNEL_PROPERTIES *pTunnel;
55722 + if (FindTunnel (&args->PsbKey, &pTunnel, ALL_TRUNKS) == TRUE)
55724 + RSVP_LSP_PROPERTIES *pRsvpLsp = GetWorkingRsvpLsp (pTunnel);
55725 + if (pRsvpLsp != NULL)
55727 + if (pRsvpLsp->tunneled == TRUE)
55729 + SM_CALL_T *pCall;
55730 + INGRESS_API *pOpenLspParams;
55731 + RSVP_TUNNEL_PROPERTIES *pTunnelsTunnel;
55732 + if (FindTunnel
55733 + (&pRsvpLsp->forw_info.tunnel, &pTunnelsTunnel,
55734 + ALL_TRUNKS) != TRUE)
55736 + zlog_err ("\ncannot find tunnels tunnel %s %d...", __FILE__,
55737 + __LINE__);
55738 + return FALSE;
55740 + if ((pOpenLspParams = CreateRequest2Signalling (pRsvpLsp->forw_info.tunnel.Session.Dest, pRsvpLsp->forw_info.tunnel.Session.TunnelId, 0, NULL, pTunnelsTunnel->RequiredBW + args->BW, 4, 4, /* Default for now */
55741 + LOCAL_PROTECTION_DESIRED,
55742 + 0, 0,
55744 + /* Default for now */
55745 + )) == NULL)
55747 + zlog_err ("\ncannot create request %s %d", __FILE__,
55748 + __LINE__);
55749 + return FALSE;
55752 + if ((pCall =
55753 + lsp_sm_sync_invoke (pSm, pOpenLspParams,
55754 + INGRESS_LSP_REQUEST_EVENT)) == NULL)
55756 + zlog_err ("\ncannot invoke lsp sm %s %d", __FILE__,
55757 + __LINE__);
55758 + return FALSE;
55760 + else
55762 + sm_call (pCall);
55763 + return TRUE;
55768 + return FALSE;
55771 +static void
55772 +constraint_route_resolution_sm_destroy (SM_T * pSm)
55774 + XFREE (MTYPE_TE, pSm->data);
55775 + sm_gen_free (pSm);
55777 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_crr.h quagga-mpls/rsvpd/te_crr.h
55778 --- quagga/rsvpd/te_crr.h 1969-12-31 18:00:00.000000000 -0600
55779 +++ quagga-mpls/rsvpd/te_crr.h 2007-06-18 23:55:58.000000000 -0500
55780 @@ -0,0 +1,111 @@
55782 +#ifndef __CONSTRAINT_ROUTE_RESOLUTION_SM_H__
55783 +#define __CONSTRAINT_ROUTE_RESOLUTION_SM_H__
55785 +typedef enum
55787 + CONSTAINT_ROUTE_RESOLUTION_SM_ADAPTIVITY_STATE = INIT_STATE + 1,
55788 + CONSTRAINT_ROUTE_RESOLUTION_SM_MAX_STATE
55789 +} CONSTRAINT_ROUTE_RESOLUTION_SM_STATE_E;
55791 +typedef enum
55793 + LOCAL_IF_DEST,
55794 + NEXT_HOP_DEST,
55795 + INTRA_AREA_DEST,
55796 + OUT_OF_AREA_DEST,
55797 + UNKNOWN_DEST
55798 +} DESTINATION_TYPE_E;
55800 +typedef enum
55802 + OUTPUT_EGRESS,
55803 + OUTPUT_NEXT_HOP,
55804 + OUTPUT_PATH,
55805 + OUTPUT_LSP,
55806 + OUTPUT_LSP_SETUP_PENDING,
55807 + OUTPUT_UNREACHABLE,
55808 + OUTPUT_CAC_FAILED
55809 +} CONSTRAINT_ROUTE_RESOLUTION_RC_E;
55811 +typedef struct
55813 + IPV4_ADDR dest; /* IN */
55814 + float BW; /* IN */
55815 + uns32 ExclColorMask; /* IN */
55816 + uns32 InclAnyColorMask; /* IN */
55817 + uns32 InclColorMask; /* IN */
55818 + uns32 HopCount; /* IN */
55819 + PSB_KEY PsbKey; /* IN */
55820 + uns32 AvoidHopNumber; /* IN */
55821 + IPV4_ADDR *AvoidHopsArray; /* IN */
55822 + uns32 ExcludeHopNumber; /* IN */
55823 + IPV4_ADDR *ExcludeHopsArray; /* IN */
55824 + uns32 LinkBwNumber; /* IN */
55825 + void *pLinkBw; /* IN */
55826 + uns8 SetupPriority; /* IN */
55827 + uns8 HoldPriority; /* IN */
55828 + uns32 OutIf; /* OUT */
55829 + IPV4_ADDR OutNHop; /* OUT */
55830 + BOOL tunneled;
55831 + union
55833 + struct
55835 + uns32 ErHopNumber; /* OUT */
55836 + IPV4_ADDR *pErHop; /* OUT */
55837 + } path;
55838 + PSB_KEY tunnel;
55839 + } data;
55840 + CONSTRAINT_ROUTE_RESOLUTION_RC_E rc;
55841 +} CONSTRAINT_ROUTE_RESOLUTION_ARGS;
55843 +typedef struct cr_req_list
55845 + void *pSm;
55846 + void *pParentSm;
55847 + struct cr_req_list *next;
55848 +} CR_REQUESTS_LIST;
55850 +typedef struct
55852 + PATRICIA_NODE Node;
55853 + IPV4_ADDR dest;
55854 + CR_REQUESTS_LIST *pCrReqList;
55855 +} CR_REQ_NODE;
55857 +typedef struct
55859 + int handle;
55860 + int instance;
55861 +} CR_CLIENT_KEY;
55863 +typedef struct
55865 + PATRICIA_NODE Node;
55866 + CR_CLIENT_KEY key;
55867 + IPV4_ADDR dest;
55868 +} CR_CLIENT_NODE;
55870 +typedef struct
55872 + CONSTRAINT_ROUTE_RESOLUTION_ARGS *args;
55873 +} CONSTRAINT_ROUTE_RESOLUTION_SM_DATA;
55875 +extern PATRICIA_TREE ConstraintRouteResReqTree;
55876 +extern PATRICIA_TREE ConstraintRouteResClientsTree;
55877 +SM_CALL_T *constraint_route_resolution_sm_invoke (SM_T * caller, void *data);
55878 +SM_CALL_T *constraint_route_resolution_sm_handler (SM_T * pSm,
55879 + SM_EVENT_T * sm_data);
55881 +int SelectPath (PATH_L_LIST * pPaths,
55882 + CONSTRAINT_ROUTE_RESOLUTION_ARGS * args, PATH ** ppPath);
55883 +int SelectOutIf (TE_LINK_L_LIST * pTeLinks,
55884 + uns32 * OutIf,
55885 + CONSTRAINT_ROUTE_RESOLUTION_ARGS * args,
55886 + BOOL PerformAllocation);
55887 +void CspfReply (IPV4_ADDR dest, void *handle);
55889 +void UnregisterClient (int handle, int TunnelId);
55891 +#endif
55892 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_cspf.h quagga-mpls/rsvpd/te_cspf.h
55893 --- quagga/rsvpd/te_cspf.h 1969-12-31 18:00:00.000000000 -0600
55894 +++ quagga-mpls/rsvpd/te_cspf.h 2007-06-18 23:55:58.000000000 -0500
55895 @@ -0,0 +1,50 @@
55897 +#ifndef _CSPF_REQ_H_
55898 +#define _CSPF_REQ_H_
55900 +#define CSPF_REQ 1
55901 +#define BW_UPDATE_REQ 2
55902 +#define HELLO_REQ 3
55903 +#define REMOTE_BW_UPDATE_REQ 4
55905 +typedef struct
55907 + struct in_addr LocalIp;
55908 + struct in_addr RemoteIp;
55909 + float Bw;
55910 +} LINK_BW;
55912 +typedef struct
55914 + struct in_addr Destination;
55915 + int Priority;
55916 + int ExcludeColorMask;
55917 + int IncludeAnyColorMask;
55918 + int IncludeColorMask;
55919 + int HopCountLimit;
55920 + float Bw;
55921 + int LinkBwCount;
55922 + int Hops2AvoidCount;
55923 + int Hops2ExcludeCount;
55924 + LINK_BW *pLinkBw;
55925 + struct in_addr *Hops2Avoid;
55926 + struct in_addr *Hops2Exclude;
55927 + void *handle;
55928 +} CSPF_REQUEST;
55930 +typedef struct
55932 + int IfIndex;
55933 + float MaxResBw;
55934 + float ResBw[8];
55935 +} BW_UPDATE_REQUEST;
55937 +typedef struct
55939 + struct in_addr RouterId;
55940 + struct in_addr LocalIp;
55941 + struct in_addr RemoteIp;
55942 + float ResBw[8];
55943 +} REMOTE_BW_UPDATE_REQUEST;
55945 +#endif
55946 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_frr.c quagga-mpls/rsvpd/te_frr.c
55947 --- quagga/rsvpd/te_frr.c 1969-12-31 18:00:00.000000000 -0600
55948 +++ quagga-mpls/rsvpd/te_frr.c 2007-06-18 23:55:58.000000000 -0500
55949 @@ -0,0 +1,1661 @@
55950 +/* Module: fast_reroute.c
55951 + Contains: TE application fast-reroute state machine
55952 + functions.
55953 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
55954 + */
55955 +#include "te.h"
55956 +#include "mpls_rtm.h"
55959 +PATRICIA_TREE FastReRouteSmTree;
55961 +static SM_CALL_T *
55962 +fast_reroute_sm_empty_handler (SM_T * pSm, SM_EVENT_T * sm_data)
55964 + zlog_err ("\nfast_reroute_sm_empty_handler, state %d", pSm->state);
55965 + return NULL;
55968 +static SM_CALL_T *
55969 +fast_reroute_sm_init (SM_T * pSm, SM_EVENT_T * sm_event)
55971 + INGRESS_API *pOpenLspParams;
55972 + PSB_KEY PsbKey;
55973 + RSVP_TUNNEL_PROPERTIES *pTunnel;
55974 + RSVP_LSP_PROPERTIES *pRsvpLsp;
55975 + TUNNEL_KEY_T tunnel_key;
55976 + SM_CALL_T *pCall = NULL;
55977 + FRR_SM_DATA *pFrrSmData = pSm->data;
55978 + FRR_SM_ENTRY *pFrrEntry = &pFrrSmData->FrrSmEntry;
55980 + switch (sm_event->event)
55982 + case BYPASS_SETUP_REQ_EVENT:
55983 + if ((pOpenLspParams = XMALLOC (MTYPE_TE, sizeof (INGRESS_API))) == NULL)
55985 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
55986 + /* Do some clean up here */
55987 + return NULL;
55989 + memset (&PsbKey, 0, sizeof (PSB_KEY));
55990 + PsbKey.Session.Dest = pFrrEntry->frr_key.merge_node;
55991 + pOpenLspParams->TunnelId = NewTunnelId (&PsbKey);
55992 + pOpenLspParams->ErHops2Exclude[0] = pFrrEntry->frr_key.protected_node;
55993 + pOpenLspParams->ErHops2Exclude[1] =
55994 + pFrrEntry->frr_key.prohibited_penultimate_node;
55995 + pOpenLspParams->Egress = pFrrEntry->frr_key.merge_node;
55996 + pOpenLspParams->BW = 0;
55997 + pOpenLspParams->SetupPriority = 4;
55998 + pOpenLspParams->HoldPriority = 4;
55999 + pFrrEntry->BypassTunnelId = pOpenLspParams->tunnel_id;
56000 + if ((pCall =
56001 + lsp_sm_sync_invoke (pSm, pOpenLspParams,
56002 + INGRESS_LSP_REQUEST_EVENT)) == NULL)
56004 + zlog_err ("\ncan not invoke sm %s %d", __FILE__, __LINE__);
56006 + else
56007 + sm_call (pCall);
56008 + break;
56009 + case INGRESS_LSP_OPERATION_COMPLETE_EVENT:
56010 + if (pFrrEntry->bypass_retry_timer.is_active == TRUE)
56012 + te_stop_timer (&pFrrEntry->bypass_retry_timer);
56014 + pSm->state = FAST_REROUTE_SM_UP_STATE;
56015 + memset (&PsbKey, 0, sizeof (PSB_KEY));
56016 + PsbKey.Session.Dest = pFrrEntry->frr_key.merge_node;
56017 + PsbKey.Session.TunnelId = pFrrEntry->BypassTunnelId;
56018 + PsbKey.Session.ExtTunelId = rdb_get_router_id ();
56019 + if (FindTunnel (&PsbKey, &pTunnel, ALL_TRUNKS) == TRUE)
56021 + if ((pRsvpLsp = GetWorkingRsvpLsp (pTunnel)) != NULL)
56023 + pFrrSmData->BackupOutIf = pRsvpLsp->oIfIndex;
56024 + pFrrSmData->BypassTunnelsLabel = pRsvpLsp->Label;
56025 + memset (&tunnel_key, 0, sizeof (TUNNEL_KEY_T));
56026 + tunnel_key.Dest = PsbKey.Session.Dest;
56027 + tunnel_key.TunnelId = PsbKey.Session.TunnelId;
56028 + tunnel_key.Source = PsbKey.Session.ExtTunelId;
56029 + /*if(CreateRsvpRequest(rdb_get_router_id(),
56030 + GetLSP(&tunnel_key),
56031 + 100,900000,
56032 + 100,900000,
56033 + FALSE,FALSE,
56034 + pFrrSmData->card) != E_OK)
56036 + zlog_info("\ncannnot create RSVP instance on LSP-Tunnel");
56037 + } HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
56039 + else
56041 + zlog_err ("\ncannot get working RSVP LSP %s %d", __FILE__,
56042 + __LINE__);
56045 + else
56047 + zlog_err ("\ncannot find tunnel %x %x %x %s %d",
56048 + PsbKey.Session.Dest,
56049 + PsbKey.Session.TunnelId,
56050 + PsbKey.Session.ExtTunelId, __FILE__, __LINE__);
56052 + UpdateIfWithBacupInfo (pFrrSmData);
56053 + break;
56054 + case INGRESS_LSP_OPERATION_FAILED_EVENT:
56055 + zlog_info ("\nBypass tunnel setup is failed %x %x %x %s %d",
56056 + pFrrEntry->frr_key.protected_node,
56057 + pFrrEntry->frr_key.merge_node,
56058 + pFrrEntry->frr_key.OutIfIndex, __FILE__, __LINE__);
56059 + pFrrEntry->bypass_retry_timer.data.bypass_retry_data =
56060 + pFrrEntry->frr_key;
56061 + if (te_start_timer
56062 + (&pFrrEntry->bypass_retry_timer, BYPASS_TUNNEL_RETRY_EXPIRY,
56063 + 10000) != E_OK)
56065 + zlog_err ("\ncannot start timer %s %d", __FILE__, __LINE__);
56067 + pSm->state = FAST_REROUTE_RETRY_STATE;
56068 + break;
56069 + default:
56070 + zlog_err ("\nDefault case reached %s %d", __FILE__, __LINE__);
56072 + return NULL;
56075 +static SM_CALL_T *
56076 +fast_reroute_sm_up (SM_T * pSm, SM_EVENT_T * sm_event)
56078 + FRR_SM_DATA *pFrrSmData = pSm->data;
56079 + FRR_SM_ENTRY *pFrrEntry = &pFrrSmData->FrrSmEntry;
56080 + SM_CALL_T *pCall = NULL;
56081 + TUNNEL_KEY_T tunnel_key;
56083 + switch (sm_event->event)
56085 + case BYPASS_SETUP_REQ_EVENT:
56086 + UpdateIfWithBacupInfo (pFrrSmData);
56087 + break;
56088 + case INGRESS_LSP_OPERATION_FAILED_EVENT:
56089 + BypassTunnelFailed (pFrrSmData);
56090 + pFrrEntry->bypass_retry_timer.data.bypass_retry_data =
56091 + pFrrEntry->frr_key;
56092 + if (te_start_timer
56093 + (&pFrrEntry->bypass_retry_timer, BYPASS_TUNNEL_RETRY_EXPIRY,
56094 + 10000) != E_OK)
56096 + zlog_info ("\ncannot start timer %s %d", __FILE__, __LINE__);
56098 + memset (&tunnel_key, 0, sizeof (TUNNEL_KEY_T));
56099 + tunnel_key.Dest = pFrrEntry->frr_key.merge_node;
56100 + tunnel_key.TunnelId = pFrrEntry->BypassTunnelId;
56101 + tunnel_key.Source = rdb_get_router_id ();
56102 + /*if(DestroyRsvpRequest(rdb_get_router_id(),
56103 + GetLSP(&tunnel_key),
56104 + pFrrSmData->card) != E_OK)
56106 + zlog_info("\ncannot put down RSVP");
56107 + } HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
56108 + pSm->state = FAST_REROUTE_RETRY_STATE;
56109 + break;
56110 + default:
56111 + zlog_err ("\nDefault case reached %s %d", __FILE__, __LINE__);
56113 + return pCall;
56116 +static SM_CALL_T *
56117 +fast_reroute_sm_retry (SM_T * pSm, SM_EVENT_T * sm_event)
56119 + PSB_KEY PsbKey;
56120 + RSVP_TUNNEL_PROPERTIES *pTunnel;
56121 + RSVP_LSP_PROPERTIES *pRsvpLsp;
56122 + TUNNEL_KEY_T tunnel_key;
56123 + SM_CALL_T *pCall = NULL;
56124 + FRR_SM_DATA *pFrrSmData = pSm->data;
56125 + FRR_SM_ENTRY *pFrrEntry = &pFrrSmData->FrrSmEntry;
56127 + switch (sm_event->event)
56129 + case INGRESS_LSP_OPERATION_COMPLETE_EVENT:
56130 + if (pFrrEntry->bypass_retry_timer.is_active == TRUE)
56132 + te_stop_timer (&pFrrEntry->bypass_retry_timer);
56134 + pSm->state = FAST_REROUTE_SM_UP_STATE;
56135 + memset (&PsbKey, 0, sizeof (PSB_KEY));
56136 + PsbKey.Session.Dest = pFrrEntry->frr_key.merge_node;
56137 + PsbKey.Session.TunnelId = pFrrEntry->BypassTunnelId;
56138 + PsbKey.Session.ExtTunelId = rdb_get_router_id ();
56139 + if (FindTunnel (&PsbKey, &pTunnel, ALL_TRUNKS) == TRUE)
56141 + if ((pRsvpLsp = GetWorkingRsvpLsp (pTunnel)) != NULL)
56143 + pFrrSmData->BackupOutIf = pRsvpLsp->oIfIndex;
56144 + pFrrSmData->BypassTunnelsLabel = pRsvpLsp->Label;
56145 + memset (&tunnel_key, 0, sizeof (TUNNEL_KEY_T));
56146 + tunnel_key.Dest = PsbKey.Session.Dest;
56147 + tunnel_key.TunnelId = PsbKey.Session.TunnelId;
56148 + tunnel_key.Source = PsbKey.Session.ExtTunelId;
56149 + /*if(CreateRsvpRequest(rdb_get_router_id(),
56150 + GetLSP(&tunnel_key),
56151 + 100,900000,
56152 + 100,900000,
56153 + FALSE,FALSE,
56154 + pFrrSmData->card) != E_OK)
56156 + zlog_info("\ncannnot create RSVP instance on LSP-Tunnel");
56157 + } HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
56159 + else
56161 + zlog_err ("\ncannot get working RSVP LSP %s %d", __FILE__,
56162 + __LINE__);
56165 + else
56167 + zlog_err ("\ncannot find tunnel %x %x %x %s %d",
56168 + PsbKey.Session.Dest,
56169 + PsbKey.Session.TunnelId,
56170 + PsbKey.Session.ExtTunelId, __FILE__, __LINE__);
56172 + UpdateIfWithBacupInfo (pFrrSmData);
56173 + pSm->state = FAST_REROUTE_SM_UP_STATE;
56174 + break;
56175 + case INGRESS_LSP_OPERATION_FAILED_EVENT:
56176 + zlog_info ("\nBypass tunnel setup is failed %x %x %x %s %d",
56177 + pFrrEntry->frr_key.protected_node,
56178 + pFrrEntry->frr_key.merge_node,
56179 + pFrrEntry->frr_key.OutIfIndex, __FILE__, __LINE__);
56180 + pFrrEntry->bypass_retry_timer.data.bypass_retry_data =
56181 + pFrrEntry->frr_key;
56182 + if (te_start_timer
56183 + (&pFrrEntry->bypass_retry_timer, BYPASS_TUNNEL_RETRY_EXPIRY,
56184 + 10000) != E_OK)
56186 + zlog_err ("\ncannot start timer %s %d", __FILE__, __LINE__);
56188 + break;
56189 + case BYPASS_SETUP_REQ_EVENT:
56190 + break;
56191 + default:
56192 + zlog_err ("\nDefault case reached %s %d", __FILE__, __LINE__);
56194 + return NULL;
56197 +static SM_CALL_T *(*lsp_sm_event_handler[FAST_REROUTE_SM_MAX_STATE])
56198 + (HANDLE sm_handle, SM_EVENT_T * sm_data) =
56200 +fast_reroute_sm_empty_handler,
56201 + fast_reroute_sm_init, fast_reroute_sm_up, fast_reroute_sm_retry};
56203 +SM_CALL_T *
56204 +fast_reroute_sm_handler (HANDLE sm_handle, SM_EVENT_T * sm_data)
56206 + SM_T *pSm = (SM_T *) sm_handle;
56207 + if (sm_data == NULL)
56209 + zlog_err ("\nfatal: sm_data is NULL %s %d", __FILE__, __LINE__);
56210 + FastReRouteSmDestroy (pSm);
56211 + return NULL;
56213 + if ((pSm->state < INIT_STATE) || (pSm->state >= FAST_REROUTE_SM_MAX_STATE))
56215 + FastReRouteSmDestroy (pSm);
56216 + return NULL;
56218 + return lsp_sm_event_handler[pSm->state] (pSm, sm_data);
56221 +SM_CALL_T *
56222 +fast_reroute_sm_sync_invoke (FRR_SM_CALL * pFrrCall, SM_EVENT_E event)
56224 + SM_T *pSm;
56225 + SM_CALL_T *pEvent = NULL;
56226 + FRR_SM_DATA *pFrrSmData;
56227 + FRR_SM_ENTRY *pFrrEntry;
56228 + FRR_LABEL_ENTRY *pLabelEntry;
56229 + FRR_INGRESS_ENTRY *pIngressEntry;
56230 + PATRICIA_PARAMS params;
56231 + BOOL malloc_performed = FALSE;
56232 + zlog_info ("\ninside of fast_reroute_sm_sync_invoke");
56233 + if (event == BYPASS_SETUP_REQ_EVENT)
56235 + if ((pFrrEntry = FindFastRerouteSm (&pFrrCall->frr_key)) == NULL)
56237 + zlog_info ("\nnew FRR SM creation...");
56238 + pSm = sm_gen_alloc (0, FAST_REROUTE_SM);
56239 + if (pSm == NULL)
56241 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
56242 + return NULL;
56245 + if ((pFrrSmData = XMALLOC (MTYPE_TE, sizeof (FRR_SM_DATA))) == NULL)
56247 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
56248 + sm_gen_free (pSm);
56249 + return NULL;
56251 + malloc_performed = TRUE;
56252 + pFrrEntry = &pFrrSmData->FrrSmEntry;
56253 + pFrrEntry->frr_key = pFrrCall->frr_key;
56254 + pFrrEntry->Node.key_info = &pFrrEntry->frr_key;
56255 + pFrrEntry->sm_handle = pSm;
56256 + pSm->data = pFrrSmData;
56257 + params.key_size = sizeof (unsigned int);
56258 + params.info_size = 0;
56259 + zlog_info ("\nLabel's tree initialization...");
56260 + if (patricia_tree_init (&pFrrEntry->labels_tree, &params) != E_OK)
56262 + zlog_err ("\ncannot initiate patricia tree (per SM) for FRR");
56263 + sm_gen_free (pSm);
56264 + XFREE (MTYPE_TE, pFrrSmData);
56265 + return NULL;
56268 + params.key_size = sizeof (PSB_KEY);
56269 + params.info_size = 0;
56270 + zlog_info ("\nIngress tree initialization...");
56271 + if (patricia_tree_init (&pFrrEntry->ingress_tree, &params) != E_OK)
56273 + zlog_err ("\ncannot initiate patricia tree (per SM) for FRR");
56274 + sm_gen_free (pSm);
56275 + XFREE (MTYPE_TE, pFrrSmData);
56276 + return NULL;
56279 + zlog_info ("\nadding FRR SM node to the tree...");
56281 + if (patricia_tree_add (&FastReRouteSmTree, &pFrrEntry->Node) !=
56282 + E_OK)
56284 + sm_gen_free (pSm);
56285 + XFREE (MTYPE_TE, pFrrSmData);
56286 + return NULL;
56289 + else
56291 + pSm = pFrrEntry->sm_handle;
56293 + if (pFrrCall->Label != 0)
56295 + if ((pLabelEntry =
56296 + XMALLOC (MTYPE_TE, sizeof (FRR_LABEL_ENTRY))) == NULL)
56298 + zlog_err ("\nmalloc failed...");
56299 + if (malloc_performed == TRUE)
56301 + if (patricia_tree_del (&FastReRouteSmTree, &pFrrEntry->Node)
56302 + != E_OK)
56304 + zlog_err
56305 + ("\ncannot delete FRR ENTRY from FastReRouteTree");
56306 + return NULL;
56308 + XFREE (MTYPE_TE, pFrrSmData);
56309 + sm_gen_free (pSm);
56311 + return NULL;
56313 + pLabelEntry->Label = pFrrCall->Label;
56314 + pLabelEntry->Node.key_info = &pLabelEntry->Label;
56315 + if (patricia_tree_add (&pFrrEntry->labels_tree, &pLabelEntry->Node)
56316 + != E_OK)
56318 + if (patricia_tree_get (&pFrrEntry->labels_tree,
56319 + (const uns8 *) &pLabelEntry->Label) ==
56320 + NULL)
56322 + zlog_err ("\ncannot add label frr entry - unknown reason");
56324 + XFREE (MTYPE_TE, pLabelEntry);
56325 + return NULL;
56327 + PlatformWideLabelSpace[pLabelEntry->Label -
56328 + 1].BackupForwardingInformation.frr_key =
56329 + pFrrCall->frr_key;
56330 + PlatformWideLabelSpace[pLabelEntry->Label -
56331 + 1].BackupForwardingInformation.MergeNode =
56332 + pFrrCall->MergeNode;
56333 + PlatformWideLabelSpace[pLabelEntry->Label -
56334 + 1].BackupForwardingInformation.PSB_KEY =
56335 + pFrrCall->PSB_KEY;
56336 + zlog_info ("\nINVOKE: %x %x %x %x %x",
56337 + PlatformWideLabelSpace[pLabelEntry->Label -
56338 + 1].BackupForwardingInformation.
56339 + PSB_KEY.Session.Dest,
56340 + PlatformWideLabelSpace[pLabelEntry->Label -
56341 + 1].BackupForwardingInformation.
56342 + PSB_KEY.Session.TunnelId,
56343 + PlatformWideLabelSpace[pLabelEntry->Label -
56344 + 1].BackupForwardingInformation.
56345 + PSB_KEY.Session.ExtTunelId,
56346 + PlatformWideLabelSpace[pLabelEntry->Label -
56347 + 1].BackupForwardingInformation.
56348 + PSB_KEY.sender.Lsp_IdNet,
56349 + PlatformWideLabelSpace[pLabelEntry->Label -
56350 + 1].BackupForwardingInformation.
56351 + PSB_KEY.sender.IPv4TunnelSenderNet);
56353 + else
56355 + RSVP_TUNNEL_PROPERTIES *pTunnel;
56356 + RSVP_LSP_PROPERTIES *pRsvpLsp;
56357 + uns16 SavedLspId;
56358 + IPV4_ADDR SavedSenderIp;
56359 + zlog_info ("\nIngress LER call...");
56360 + if ((pIngressEntry =
56361 + XMALLOC (MTYPE_TE, sizeof (FRR_INGRESS_ENTRY))) == NULL)
56363 + zlog_info ("\nmalloc failed...");
56364 + if (malloc_performed == TRUE)
56366 + if (patricia_tree_del (&FastReRouteSmTree, &pFrrEntry->Node)
56367 + != E_OK)
56369 + zlog_err
56370 + ("\ncannot delete FRR ENTRY from FastReRouteTree");
56371 + return NULL;
56373 + XFREE (MTYPE_TE, pFrrSmData);
56374 + sm_gen_free (pSm);
56376 + return NULL;
56378 + pIngressEntry->PsbKey = pFrrCall->PsbKey;
56379 + pIngressEntry->Node.key_info = &pIngressEntry->PsbKey;
56380 + zlog_info ("\nadding node to Ingress tree....");
56381 + if (patricia_tree_add
56382 + (&pFrrEntry->ingress_tree, &pIngressEntry->Node) != E_OK)
56384 + if (patricia_tree_get (&pFrrEntry->ingress_tree,
56385 + (const uns8 *) &pIngressEntry->PsbKey) ==
56386 + NULL)
56388 + zlog_err ("\ncannot add label frr entry - unknown reason");
56390 + XFREE (MTYPE_TE, pIngressEntry);
56391 + return NULL;
56393 + SavedLspId = pFrrCall->PsbKey.SenderTemplate.LspId;
56394 + SavedSenderIp = pFrrCall->PsbKey.SenderTemplate.IpAddr;
56395 + pFrrCall->PsbKey.sender.Lsp_IdNet = 0;
56396 + pFrrCall->PsbKey.sender.IPv4TunnelSenderNet = 0;
56397 + if (FindTunnel (&pFrrCall->PsbKey, &pTunnel, ALL_TRUNKS) == TRUE)
56399 + pFrrCall->PsbKey.SenderTemplate.LspId = SavedLspId;
56400 + pFrrCall->PsbKey.SenderTemplate.IpAddr = SavedSenderIp;
56401 + if (((pRsvpLsp =
56402 + FindRsvpLspByLspId (pTunnel, SavedLspId)) != NULL)
56403 + && (pRsvpLsp->tunneled == FALSE))
56405 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
56406 + frr_key = pFrrCall->frr_key;
56407 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
56408 + MergeNode = pFrrCall->MergeNode;
56409 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
56410 + PsbKey = pFrrCall->PsbKey;
56412 + else
56414 + zlog_err
56415 + ("\ncannot get RSVP LSP by LSP ID or LSP is tunneled %x %s %d",
56416 + pRsvpLsp, __FILE__, __LINE__);
56419 + else
56421 + zlog_err ("\ncannot find tunnel %x %x %x %s %d",
56422 + pFrrCall->PsbKey.Session.Dest,
56423 + pFrrCall->PsbKey.Session.TunnelId,
56424 + pFrrCall->PsbKey.Session.ExtTunelId,
56425 + __FILE__, __LINE__);
56428 + zlog_info ("\ncreation event...");
56429 + if ((pEvent =
56430 + sm_gen_sync_event_send ((HANDLE) pSm, event, NULL)) == NULL)
56432 + zlog_err ("\ncan not invoke sm %s %d", __FILE__, __LINE__);
56433 + XFREE (MTYPE_TE, pFrrSmData);
56434 + sm_gen_free (pSm);
56437 + return pEvent;
56440 +extern PATRICIA_TREE PlatformWideFreeLabels;
56441 +extern LABEL_ENTRY PlatformWideLabelSpace[LABEL_SPACE_SIZE];
56443 +uns32
56444 +UpdateIfWithSingleBacupInfo (FRR_SM_DATA * pFrrSmData,
56445 + unsigned int Label,
56446 + PSB_KEY * PSB_KEY, unsigned int MergeNodeLabel)
56448 + COMPONENT_LINK *pComponentLink;
56449 + FRR_LABEL_ENTRY *pLabelEntry;
56450 + FRR_INGRESS_ENTRY *pIngressEntry;
56451 + FRR_SM_ENTRY *pFrrEntry = &pFrrSmData->FrrSmEntry;
56453 + if (rdb_get_component_link (pFrrEntry->frr_key.OutIfIndex, /* SAME FOR NOW!!! */
56454 + pFrrEntry->frr_key.OutIfIndex, /* SAME FOR NOW!!! */
56455 + &pComponentLink) != E_OK)
56457 + zlog_err ("\ncannot get component link %s %d", __FILE__, __LINE__);
56458 + return E_ERR;
56460 + if ((pLabelEntry =
56461 + patricia_tree_get (&pFrrEntry->labels_tree,
56462 + (const uns8 *) &Label)) != NULL)
56464 + if (patricia_tree_get
56465 + (&PlatformWideFreeLabels,
56466 + (const uns8 *) &pLabelEntry->Label) == NULL)
56468 + PlatformWideLabelSpace[pLabelEntry->Label -
56469 + 1].BackupForwardingInformation.
56470 + MergeNodeLabel = MergeNodeLabel;
56471 + PlatformWideLabelSpace[pLabelEntry->Label -
56472 + 1].BackupForwardingInformation.
56473 + MergeNodeLabelValid = TRUE;
56474 + /*PlatformWideLabelSpace[pLabelEntry->Label-1].BackupForwardingInformation.PSB_KEY = *PSB_KEY; */
56475 + if (pFrrSmData->BypassTunnelsLabel != 0)
56477 + PlatformWideLabelSpace[pLabelEntry->Label -
56478 + 1].BackupForwardingInformation.
56479 + BypassTunnelsLabel = pFrrSmData->BypassTunnelsLabel;
56480 + PlatformWideLabelSpace[pLabelEntry->Label -
56481 + 1].BackupForwardingInformation.OutIf =
56482 + pFrrSmData->BackupOutIf;
56483 + zlog_info
56484 + ("\nLSR: deletion from FRR SM tree and insertion to component link tree");
56485 + if (patricia_tree_del
56486 + (&pFrrEntry->labels_tree, &pLabelEntry->Node) != E_OK)
56488 + zlog_err ("\ncannot delete node from patricia tree %s %d",
56489 + __FILE__, __LINE__);
56491 + else
56492 + if (patricia_tree_add
56493 + (&pComponentLink->ProtectionTree,
56494 + &pLabelEntry->Node) != E_OK)
56496 + zlog_err ("\ncannot add node to patricia %s %d", __FILE__,
56497 + __LINE__);
56499 + else
56501 + if (InformRsvpAboutFrr
56502 + (&PlatformWideLabelSpace[pLabelEntry->Label - 1].
56503 + BackupForwardingInformation.PSB_KEY,
56504 + PlatformWideLabelSpace[pLabelEntry->Label -
56505 + 1].allocator,
56506 + PlatformWideLabelSpace[pLabelEntry->Label - 1].IfIndex,
56507 + pFrrSmData->BackupOutIf, pFrrSmData->card,
56508 + PlatformWideLabelSpace[pLabelEntry->Label -
56509 + 1].BackupForwardingInformation.
56510 + MergeNode) != E_OK)
56512 + zlog_err ("\ncannot update LCC with backup intfo");
56517 + else
56519 + zlog_err ("\nAllocated Label %x is not really allocated %s %d...",
56520 + pLabelEntry->Label, __FILE__, __LINE__);
56523 + return E_OK;
56526 +uns32
56527 +UpdateIfWithSingleIngressBacupInfo (FRR_SM_DATA * pFrrSmData,
56528 + PSB_KEY * PsbKey,
56529 + unsigned int MergeNodeLabel)
56531 + COMPONENT_LINK *pComponentLink;
56532 + FRR_INGRESS_ENTRY *pIngressEntry;
56533 + FRR_SM_ENTRY *pFrrEntry = &pFrrSmData->FrrSmEntry;
56535 + PsbKey->SenderTemplate.LspId = ntohs (PsbKey->SenderTemplate.LspId);
56537 + if (rdb_get_component_link (pFrrEntry->frr_key.OutIfIndex, /* SAME FOR NOW!!! */
56538 + pFrrEntry->frr_key.OutIfIndex, /* SAME FOR NOW!!! */
56539 + &pComponentLink) != E_OK)
56541 + zlog_err ("\ncannot get component link %s %d", __FILE__, __LINE__);
56542 + return E_ERR;
56544 + if ((pIngressEntry =
56545 + patricia_tree_get (&pFrrEntry->ingress_tree,
56546 + (const uns8 *) PSB_KEY)) != NULL)
56548 + /* update working RSVP LSP with valid info */
56549 + if (pFrrSmData->BypassTunnelsLabel != 0)
56551 + RSVP_TUNNEL_PROPERTIES *pTunnel;
56552 + RSVP_LSP_PROPERTIES *pRsvpLsp;
56553 + uns16 SavedLspId = pIngressEntry->PSB_KEY.sender.Lsp_IdNet;
56554 + IPV4_ADDR SavedSenderIp =
56555 + pIngressEntry->PSB_KEY.sender.IPv4TunnelSenderNet;
56556 + pIngressEntry->PsbKey.SenderTemplate.LspId = 0;
56557 + pIngressEntry->PsbKey.SenderTemplate.IpAddr = 0;
56558 + if (FindTunnel (&pIngressEntry->PsbKey, &pTunnel, ALL_TRUNKS) ==
56559 + TRUE)
56561 + pIngressEntry->PsbKey.SenderTemplate.LspId = SavedLspId;
56562 + pIngressEntry->PsbKey.SenderTemplate.IpAddr = SavedSenderIp;
56563 + if (((pRsvpLsp =
56564 + FindRsvpLspByLspId (pTunnel, SavedLspId)) != NULL)
56565 + && (pRsvpLsp->tunneled == FALSE))
56567 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
56568 + MergeNodeLabelValid = TRUE;
56569 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
56570 + MergeNodeLabel = MergeNodeLabel;
56571 + /*pRsvpLsp->forw_info.path.BackupForwardingInformation.PSB_KEY = *PSB_KEY; */
56572 + if (pFrrSmData->BypassTunnelsLabel != 0)
56574 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
56575 + BypassTunnelsLabel = pFrrSmData->BypassTunnelsLabel;
56576 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
56577 + OutIf = pFrrSmData->BackupOutIf;
56578 + zlog_info
56579 + ("\nIngress: deletion from FRR SM tree and insertion to component link tree");
56580 + if (patricia_tree_del
56581 + (&pFrrEntry->ingress_tree,
56582 + &pIngressEntry->Node) != E_OK)
56584 + zlog_err
56585 + ("\ncannot delete node from patricia tree %s %d",
56586 + __FILE__, __LINE__);
56588 + else
56589 + if (patricia_tree_add
56590 + (&pComponentLink->IngressProtectionTree,
56591 + &pIngressEntry->Node) != E_OK)
56593 + zlog_err ("\ncannot add node to patricia %s %d",
56594 + __FILE__, __LINE__);
56596 + else
56598 + if (InformRsvpAboutFrr (PsbKey,
56599 + pRsvpLsp->card,
56600 + pRsvpLsp->oIfIndex,
56601 + pFrrSmData->BackupOutIf,
56602 + pRsvpLsp->forw_info.path.
56603 + BackupForwardingInformation.
56604 + MergeNode) != E_OK)
56606 + zlog_err
56607 + ("\ncannot update LCC with backup intfo");
56612 + else
56614 + if (pRsvpLsp == NULL)
56616 + zlog_err
56617 + ("\ncannot get working RSVP LSP %x %x %x %x %x %s %d",
56618 + pIngressEntry->PsbKey.Session.Dest,
56619 + pIngressEntry->PsbKey.Session.TunnelId,
56620 + pIngressEntry->PsbKey.Session.ExtTunelId, SavedLspId,
56621 + SavedSenderIp, __FILE__, __LINE__);
56623 + else
56625 + zlog_err ("\nRSVP LSP %x %x %x is tunneled %x %s %d",
56626 + pIngressEntry->PsbKey.Session.Dest,
56627 + pIngressEntry->PsbKey.Session.TunnelId,
56628 + pIngressEntry->PsbKey.Session.ExtTunelId,
56629 + pRsvpLsp->tunneled, __FILE__, __LINE__);
56635 + return E_OK;
56638 +uns32
56639 +UpdateIfWithBacupInfo (FRR_SM_DATA * pFrrSmData)
56641 + COMPONENT_LINK *pComponentLink;
56642 + FRR_LABEL_ENTRY *pLabelEntry;
56643 + FRR_INGRESS_ENTRY *pIngressLabelEntry;
56644 + unsigned int key = 0;
56645 + PSB_KEY PsbKey;
56646 + FRR_SM_ENTRY *pFrrEntry = &pFrrSmData->FrrSmEntry;
56648 + if (rdb_get_component_link (pFrrEntry->frr_key.OutIfIndex, /* SAME FOR NOW!!! */
56649 + pFrrEntry->frr_key.OutIfIndex, /* SAME FOR NOW!!! */
56650 + &pComponentLink) != E_OK)
56652 + zlog_err ("\ncannot get component link %s %d", __FILE__, __LINE__);
56653 + return E_ERR;
56655 + /* first - update LSR entries */
56656 + zlog_info ("\nupdating an LSR entries %x %x %x...",
56657 + pFrrEntry->frr_key.merge_node, pFrrEntry->frr_key.OutIfIndex,
56658 + pFrrEntry->frr_key.protected_node);
56659 + while ((pLabelEntry =
56660 + patricia_tree_getnext (&pFrrEntry->labels_tree,
56661 + (const uns8 *) &key)) != NULL)
56663 + if (patricia_tree_get
56664 + (&PlatformWideFreeLabels,
56665 + (const uns8 *) &pLabelEntry->Label) == NULL)
56667 + if (PlatformWideLabelSpace[pLabelEntry->Label - 1].
56668 + BackupForwardingInformation.MergeNodeLabelValid == TRUE)
56670 + PlatformWideLabelSpace[pLabelEntry->Label -
56671 + 1].BackupForwardingInformation.
56672 + BypassTunnelsLabel = pFrrSmData->BypassTunnelsLabel;
56673 + PlatformWideLabelSpace[pLabelEntry->Label -
56674 + 1].BackupForwardingInformation.OutIf =
56675 + pFrrSmData->BackupOutIf;
56676 + zlog_info
56677 + ("\naLSR: deletion from FRR SM tree and insertion to component link tree");
56678 + if (patricia_tree_del
56679 + (&pFrrEntry->labels_tree, &pLabelEntry->Node) != E_OK)
56681 + zlog_err ("\ncannot delete node from patricia tree %s %d",
56682 + __FILE__, __LINE__);
56684 + else
56686 + if (patricia_tree_add
56687 + (&pComponentLink->ProtectionTree,
56688 + &pLabelEntry->Node) != E_OK)
56690 + zlog_err ("\ncannot add node to patricia %s %d",
56691 + __FILE__, __LINE__);
56693 + else
56694 + if (InformRsvpAboutFrr
56695 + (&PlatformWideLabelSpace[pLabelEntry->Label - 1].
56696 + BackupForwardingInformation.PSB_KEY,
56697 + PlatformWideLabelSpace[pLabelEntry->Label -
56698 + 1].allocator,
56699 + PlatformWideLabelSpace[pLabelEntry->Label -
56700 + 1].IfIndex,
56701 + pFrrSmData->BackupOutIf, pFrrSmData->card,
56702 + PlatformWideLabelSpace[pLabelEntry->Label -
56703 + 1].
56704 + BackupForwardingInformation.MergeNode) != E_OK)
56706 + zlog_err ("\ncannot update LCC with backup intfo");
56711 + else
56713 + zlog_err ("\nAllocated Label %x is not really allocated %s %d...",
56714 + pLabelEntry->Label, __FILE__, __LINE__);
56716 + key = pLabelEntry->Label;
56718 + /* second - update Ingress entries */
56719 + memset (&PSB_KEY, 0, sizeof (PSB_KEY));
56720 + zlog_info ("\nupdating an Ingress entries...");
56721 + while ((pIngressLabelEntry =
56722 + patricia_tree_getnext (&pFrrEntry->ingress_tree,
56723 + (const uns8 *) &PSB_KEY)) != NULL)
56725 + RSVP_TUNNEL_PROPERTIES *pTunnel;
56726 + uns16 SavedLspId = pIngressLabelEntry->PSB_KEY.sender.Lsp_IdNet;
56727 + IPV4_ADDR SavedSenderIp =
56728 + pIngressLabelEntry->PSB_KEY.sender.IPv4TunnelSenderNet;
56730 + pIngressLabelEntry->PsbKey.SenderTemplate.LspId = 0;
56731 + pIngressLabelEntry->PsbKey.SenderTemplate.IpAddr = 0;
56732 + zlog_info ("\nfinding a tunnel...");
56733 + if (FindTunnel (&pIngressLabelEntry->PsbKey, &pTunnel, ALL_TRUNKS) ==
56734 + TRUE)
56736 + RSVP_LSP_PROPERTIES *pRsvpLsp;
56738 + pIngressLabelEntry->PsbKey.SenderTemplate.LspId = SavedLspId;
56739 + pIngressLabelEntry->PsbKey.SenderTemplate.IpAddr = SavedSenderIp;
56740 + zlog_info ("\nfinding an LSP...");
56741 + if (((pRsvpLsp = FindRsvpLspByLspId (pTunnel, SavedLspId)) != NULL)
56742 + && (pRsvpLsp->tunneled == FALSE))
56744 + if (pRsvpLsp->forw_info.path.BackupForwardingInformation.
56745 + MergeNodeLabelValid == TRUE)
56747 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
56748 + BypassTunnelsLabel = pFrrSmData->BypassTunnelsLabel;
56749 + pRsvpLsp->forw_info.path.BackupForwardingInformation.OutIf =
56750 + pFrrSmData->BackupOutIf;
56751 + zlog_info
56752 + ("\naIngress: deletion from FRR SM tree and insertion to component link tree");
56753 + if (patricia_tree_del
56754 + (&pFrrEntry->ingress_tree,
56755 + &pIngressLabelEntry->Node) == E_OK)
56757 + if (patricia_tree_add
56758 + (&pComponentLink->IngressProtectionTree,
56759 + &pIngressLabelEntry->Node) != E_OK)
56761 + zlog_err
56762 + ("\ncannot add entry to Ingress tree %x %x %x %x %s %d",
56763 + pComponentLink->oifIndex,
56764 + pIngressLabelEntry->PsbKey.Session.Dest,
56765 + pIngressLabelEntry->PsbKey.Session.TunnelId,
56766 + pIngressLabelEntry->PsbKey.Session.ExtTunelId,
56767 + __FILE__, __LINE__);
56769 + else
56771 + if (InformRsvpAboutFrr
56772 + (&pRsvpLsp->forw_info.path.
56773 + BackupForwardingInformation.PsbKey,
56774 + pRsvpLsp->oIfIndex, pFrrSmData->BackupOutIf,
56775 + pRsvpLsp->forw_info.path.
56776 + BackupForwardingInformation.MergeNode) != E_OK)
56778 + zlog_err
56779 + ("\ncannot update LCC with backup intfo");
56783 + else
56785 + zlog_err
56786 + ("\ncannot delete node from patricia %x %x %x %s %d",
56787 + pIngressLabelEntry->PsbKey.Session.Dest,
56788 + pIngressLabelEntry->PsbKey.Session.TunnelId,
56789 + pIngressLabelEntry->PsbKey.Session.ExtTunelId,
56790 + __FILE__, __LINE__);
56794 + else
56796 + if (pRsvpLsp == NULL)
56798 + zlog_err
56799 + ("\ncannot get working RSVP LSP %x %x %x %x %x %s %d",
56800 + pIngressLabelEntry->PsbKey.Session.Dest,
56801 + pIngressLabelEntry->PsbKey.Session.TunnelId,
56802 + pIngressLabelEntry->PsbKey.Session.ExtTunelId,
56803 + SavedLspId, SavedSenderIp, __FILE__, __LINE__);
56805 + else
56807 + zlog_err ("\nRSVP LSP %x %x %x is tunneled %x %s %d",
56808 + pIngressLabelEntry->PsbKey.Session.Dest,
56809 + pIngressLabelEntry->PsbKey.Session.TunnelId,
56810 + pIngressLabelEntry->PsbKey.Session.ExtTunelId,
56811 + pRsvpLsp->tunneled, __FILE__, __LINE__);
56815 + else
56817 + zlog_err ("\ncannot find tunnel %x %x %x %s %d", __FILE__,
56818 + __LINE__);
56820 + PsbKey = pIngressLabelEntry->PsbKey;
56822 + return E_OK;
56825 +FRR_SM_ENTRY *
56826 +FindFastRerouteSm (FRR_SM_KEY * frr_key)
56828 + return patricia_tree_get (&FastReRouteSmTree, (const uns8 *) frr_key);
56831 +void
56832 +InitFastReRoute ()
56834 + PATRICIA_PARAMS params;
56836 + params.key_size = sizeof (FRR_SM_KEY);
56837 + params.info_size = 0;
56838 + if (patricia_tree_init (&FastReRouteSmTree, &params) != E_OK)
56840 + zlog_err ("\ncannot initiate patricia tree for FRR");
56841 + return;
56845 +void
56846 +RRO_ChangedHook (uns32 Label,
56847 + RSVP_RRO_LSP_TUNNEL * pRro,
56848 + SESSION_OBJ * pSess,
56849 + SENDER_TEMPLATE_OBJ * pSender, uns32 IfIndex)
56851 + TE_MSG *pMsg;
56852 + /* clone RRO and send it up */
56853 + /*if((pMsg = dmsg_create(GetLcbPtr(),LTCS_EVENT_RRO_CHANGED)) == NULL)
56855 + zlog_info("\ncannot create message %s %d",__FILE__,__LINE__);
56856 + return;
56857 + } */
56858 + if (Label == 0)
56860 + zlog_info
56861 + ("\ninside of RRO_ChangedHook: Dest#%x Tunnel#%x Source#%x LspId#%x Source %x",
56862 + pSess->Dest, pSess->TunnelId, pSess->ExtTunelId, pSender->LspId,
56863 + pSender->IpAddr);
56865 + else
56867 + zlog_info ("\ninside of RRO_ChangedHook: Label#%x", Label);
56869 + if ((pRro != NULL) && (pRro->nSubObjects != 0))
56871 + if ((pMsg->info.rro_changed_hook.pRro =
56872 + XMALLOC (MTYPE_TE,
56873 + (sizeof (RSVP_RRO_LSP_TUNNEL) +
56874 + sizeof (RSVP_RRO_SUBOBJ) * (pRro->nSubObjects - 1)))) ==
56875 + NULL)
56877 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
56878 + dmsg_release (pMsg);
56879 + return;
56881 + pMsg->info.rro_changed_hook.pRro->nSubObjects = pRro->nSubObjects;
56882 + memcpy (pMsg->info.rro_changed_hook.pRro->SubObjects,
56883 + pRro->SubObjects,
56884 + sizeof (RSVP_RRO_SUBOBJ) * (pRro->nSubObjects));
56885 +#if 1
56887 + int i;
56888 + RSVP_RRO_SUBOBJ *pDbg = pMsg->info.rro_changed_hook.pRro->SubObjects;
56889 + for (i = 0; i < pMsg->info.rro_changed_hook.pRro->nSubObjects; i++)
56891 + switch (pDbg[i].SubType)
56893 + case 1:
56894 + zlog_info
56895 + ("\nobj#%d IP ADDR %x/%x prefix len %x/%x flag %x/%x", i,
56896 + pDbg[i].SubData.IPv4.Addr,
56897 + pRro->SubObjects[i].SubData.IPv4.Addr,
56898 + pDbg[i].SubData.IPv4.PrefixBitLen,
56899 + pRro->SubObjects[i].SubData.IPv4.PrefixBitLen,
56900 + pDbg[i].SubData.IPv4.Flags,
56901 + pRro->SubObjects[i].SubData.IPv4.Flags);
56902 + break;
56903 + case 3:
56904 + zlog_info
56905 + ("\nobj#%d LABEL ctype %x/%x flags %x/%x value %x/%x", i,
56906 + pDbg[i].SubData.Label.Label_CType,
56907 + pRro->SubObjects[i].SubData.Label.Label_CType,
56908 + pDbg[i].SubData.Label.Label_Flags,
56909 + pRro->SubObjects[i].SubData.Label.Label_Flags,
56910 + pDbg[i].SubData.Label.Label_Value,
56911 + pRro->SubObjects[i].SubData.Label.Label_Value);
56912 + break;
56913 + default:
56914 + zlog_info ("\nobject of unknown type %x/%x", pDbg[i].SubType,
56915 + pRro->SubObjects[i].SubType);
56919 +#endif
56921 + pMsg->info.rro_changed_hook.Label = Label;
56922 + pMsg->info.rro_changed_hook.OutIf = IfIndex;
56923 + if (pMsg->info.rro_changed_hook.Label == 0)
56925 + pMsg->info.rro_changed_hook.PSB_KEY.Session.Dest = pSess->IPDestNet;
56926 + pMsg->info.rro_changed_hook.PSB_KEY.Session.TunnelId = pSess->TunnelId;
56927 + pMsg->info.rro_changed_hook.PSB_KEY.Session.ExtTunelId =
56928 + pSess->ExtendedTunnelId;
56929 + pMsg->info.rro_changed_hook.PSB_KEY.sender.Lsp_IdNet =
56930 + pSender->Lsp_IdNet;
56931 + pMsg->info.rro_changed_hook.PSB_KEY.sender.IPv4TunnelSenderNet =
56932 + pSender->IPv4TunnelSenderNet;
56934 + if (svc_send_msg (pMsg, 1, MDS_USR_CONSOLE_SVC) != E_OK)
56935 + zlog_info ("\nFatal: can not send mds message %s %d", __FILE__, __LINE__);
56936 + if (pMsg->info.rro_changed_hook.pRro != NULL)
56937 + XFREE (MTYPE_TE, pMsg->info.rro_changed_hook.pRro);
56938 + return;
56941 +void
56942 +RRO_ChangedMsg (RRO_CHANGED_HOOK * pChangedRRO)
56944 + int i;
56945 + RSVP_RRO_LSP_TUNNEL *pRro = pChangedRRO->pRro;
56946 + FRR_SM_ENTRY *pFrrSmEntry;
56947 + FRR_SM_KEY *pFrrSmKey;
56948 + IPV4_ADDR merge_node_router_id = 0;
56949 + HJCONTEXT rdb_handle = ((LTCS_CB *) GetLcbPtr ())->rdb_layer_handle;
56951 + zlog_info ("\ninside of RRO_ChangedMsg %x", pChangedRRO->Label);
56952 + if (pChangedRRO->Label != 0)
56954 + pFrrSmKey =
56955 + &PlatformWideLabelSpace[pChangedRRO->Label -
56956 + 1].BackupForwardingInformation.frr_key;
56957 + pFrrSmEntry = FindFastRerouteSm (pFrrSmKey);
56958 + if (pFrrSmEntry == NULL)
56960 + zlog_err ("\ncannot get FRR SM entry for %x %x %x %s %d",
56961 + pFrrSmKey->merge_node, pFrrSmKey->OutIfIndex,
56962 + pFrrSmKey->protected_node, __FILE__, __LINE__);
56963 + return;
56966 + else
56968 + RSVP_TUNNEL_PROPERTIES *pTunnel;
56969 + uns16 SavedLspId = pChangedRRO->PSB_KEY.sender.Lsp_IdNet;
56970 + IPV4_ADDR SavedSenderIp =
56971 + pChangedRRO->PSB_KEY.sender.IPv4TunnelSenderNet;
56973 + pChangedRRO->PSB_KEY.Session.Dest =
56974 + ntohl (pChangedRRO->PSB_KEY.Session.Dest);
56976 + pChangedRRO->PSB_KEY.sender.Lsp_IdNet = 0;
56977 + pChangedRRO->PSB_KEY.sender.IPv4TunnelSenderNet = 0;
56979 + if (FindTunnel (&pChangedRRO->PSB_KEY, &pTunnel, ALL_TRUNKS) == TRUE)
56981 + RSVP_LSP_PROPERTIES *pRsvpLsp;
56983 + pChangedRRO->PSB_KEY.sender.Lsp_IdNet = ntohs (SavedLspId);
56984 + pChangedRRO->PSB_KEY.sender.IPv4TunnelSenderNet = SavedSenderIp;
56986 + if (((pRsvpLsp =
56987 + FindRsvpLspByLspId (pTunnel, ntohs (SavedLspId))) != NULL)
56988 + && (pRsvpLsp->tunneled == FALSE))
56990 + pFrrSmKey =
56991 + &pRsvpLsp->forw_info.path.BackupForwardingInformation.frr_key;
56992 + pFrrSmEntry = FindFastRerouteSm (pFrrSmKey);
56993 + if (pFrrSmEntry == NULL)
56995 + zlog_err
56996 + ("\ncannot get FRR SM entry for %x/%x %x/%x %x/%x %s %d",
56997 + pFrrSmKey->merge_node,
56998 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
56999 + frr_key.merge_node, pFrrSmKey->OutIfIndex,
57000 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
57001 + frr_key.OutIfIndex, pFrrSmKey->protected_node,
57002 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
57003 + frr_key.protected_node, __FILE__, __LINE__);
57004 + return;
57007 + else
57009 + if (pRsvpLsp == NULL)
57011 + zlog_err
57012 + ("\ncannot get working RSVP LSP for %x %x %x %x %x %s %d",
57013 + pChangedRRO->PSB_KEY.Session.Dest,
57014 + pChangedRRO->PSB_KEY.Session.TunnelId,
57015 + pChangedRRO->PSB_KEY.Session.ExtTunelId, SavedLspId,
57016 + SavedSenderIp, __FILE__, __LINE__);
57018 + else
57020 + zlog_err ("\nRSVP LSP %x %x %x %x %x is tunneled %x %s %d",
57021 + pChangedRRO->PSB_KEY.Session.Dest,
57022 + pChangedRRO->PSB_KEY.Session.TunnelId,
57023 + pChangedRRO->PSB_KEY.Session.ExtTunelId,
57024 + SavedLspId,
57025 + SavedSenderIp,
57026 + pRsvpLsp->tunneled, __FILE__, __LINE__);
57028 + return;
57031 + else
57033 + zlog_err ("\ncannot find tunnel %x %x %x %x %x %s %d",
57034 + pChangedRRO->PSB_KEY.Session.Dest,
57035 + pChangedRRO->PSB_KEY.Session.TunnelId,
57036 + pChangedRRO->PSB_KEY.Session.ExtTunelId,
57037 + SavedLspId, SavedSenderIp, __FILE__, __LINE__);
57038 + return;
57043 + if (pFrrSmEntry == NULL)
57045 + zlog_err ("\ncannot find FastReRoute SM by key %x %x %x",
57046 + pFrrSmKey->merge_node,
57047 + pFrrSmKey->OutIfIndex, pFrrSmKey->protected_node);
57048 + return;
57050 + if (rdb_remote_link_router_id_get (rdb_handle,
57051 + pFrrSmKey->merge_node,
57052 + &merge_node_router_id) != E_OK)
57054 + zlog_err ("\ncannot get merge node's %x router ID %s %d",
57055 + pFrrSmKey->merge_node, __FILE__, __LINE__);
57057 + zlog_info ("\nRouterID of the merge node %x", merge_node_router_id);
57059 + if (pRro != NULL)
57061 + for (i = 0; i < pRro->nSubObjects; i++)
57063 + if (pRro->SubObjects[i].SubType == RSVP_RRO_SUBOBJ_TYPE_IPV4_ADDR)
57065 + IPV4_ADDR node_router_id = 0;
57066 + if (rdb_remote_link_router_id_get (rdb_handle,
57067 + pRro->SubObjects[i].SubData.
57068 + IPv4.Addr,
57069 + &node_router_id) != E_OK)
57071 + node_router_id = pRro->SubObjects[i].SubData.IPv4.Addr;
57074 + zlog_info ("\nnode#%d/%x router ID %x",
57075 + i,
57076 + pRro->SubObjects[i].SubData.IPv4.Addr,
57077 + node_router_id);
57079 + if ((node_router_id == merge_node_router_id) &&
57080 + (i < (pRro->nSubObjects - 1)))
57082 + if ((pRro->SubObjects[i + 1].SubType ==
57083 + RSVP_RRO_SUBOBJ_TYPE_LABEL_OBJ)
57084 + && (pRro->SubObjects[i + 1].SubData.Label.Label_Flags !=
57085 + 0))
57087 + /* call here SM */
57088 + if (pChangedRRO->Label != 0)
57090 + UpdateIfWithSingleBacupInfo (((SM_T *) pFrrSmEntry->
57091 + sm_handle)->data,
57092 + pChangedRRO->Label,
57093 + &pChangedRRO->PSB_KEY,
57094 + pRro->SubObjects[i +
57095 + 1].
57096 + SubData.Label.
57097 + Label_Value);
57099 + else
57101 + UpdateIfWithSingleIngressBacupInfo (((SM_T *)
57102 + pFrrSmEntry->
57103 + sm_handle)->
57104 + data,
57105 + &pChangedRRO->
57106 + PSB_KEY,
57107 + pRro->
57108 + SubObjects[i +
57109 + 1].
57110 + SubData.Label.
57111 + Label_Value);
57113 + return;
57115 + else
57116 + if ((pRro->SubObjects[i + 1].SubType ==
57117 + RSVP_RRO_SUBOBJ_TYPE_LABEL_OBJ)
57118 + && (pRro->SubObjects[i + 1].SubData.Label.
57119 + Label_Flags == 0))
57121 + zlog_err
57122 + ("\nMerge node does not use platform-wide label space");
57124 + else
57126 + zlog_err
57127 + ("\nThere is no label object after hop object");
57130 + else if (merge_node_router_id == node_router_id)
57132 + zlog_err ("\nMerge node is found but it is last object");
57136 + XFREE (MTYPE_TE, pRro);
57138 + zlog_err ("\nMerge node is not found %s %d", __FILE__, __LINE__);
57141 +void
57142 +FrrLabelRelease (unsigned int Label)
57144 + FRR_SM_KEY *pFrrSmKey;
57145 + FRR_SM_ENTRY *pFrrSmEntry;
57146 + FRR_LABEL_ENTRY *pLabelEntry;
57147 + COMPONENT_LINK *pComponentLink;
57148 + /* validate the Label here */
57149 + zlog_info ("\ninside of FrrLabelRelease %x", Label);
57150 + pFrrSmKey =
57151 + &PlatformWideLabelSpace[Label - 1].BackupForwardingInformation.frr_key;
57152 + if ((pFrrSmEntry = FindFastRerouteSm (pFrrSmKey)) != NULL)
57154 + if ((pLabelEntry =
57155 + patricia_tree_get (&pFrrSmEntry->labels_tree,
57156 + (const uns8 *) &Label)) != NULL)
57158 + zlog_info ("\nLabel entry is on FRR's tree...");
57159 + if (patricia_tree_del
57160 + (&pFrrSmEntry->labels_tree, &pLabelEntry->Node) != E_OK)
57162 + zlog_err ("\ncannot delete node from patricia %s %d", __FILE__,
57163 + __LINE__);
57164 + return;
57166 + XFREE (MTYPE_TE, pLabelEntry);
57167 + return;
57170 + else
57172 + zlog_err ("\ncannot find FRR SM entry %x %x %x %s %d",
57173 + pFrrSmKey->merge_node,
57174 + pFrrSmKey->OutIfIndex,
57175 + pFrrSmKey->protected_node, __FILE__, __LINE__);
57176 + return;
57178 + if (rdb_get_component_link (((LTCS_CB *) GetLcbPtr ())->rdb_layer_handle, pFrrSmEntry->frr_key.OutIfIndex, /* SAME FOR NOW!!! */
57179 + pFrrSmEntry->frr_key.OutIfIndex, /* SAME FOR NOW!!! */
57180 + &pComponentLink) != E_OK)
57182 + zlog_err ("\ncannot get component link %s %d", __FILE__, __LINE__);
57183 + return;
57185 + zlog_info ("\nLooking for the label entry on component link's tree...");
57186 + if ((pLabelEntry =
57187 + patricia_tree_get (&pComponentLink->ProtectionTree,
57188 + (const uns8 *) &Label)) != NULL)
57190 + if (patricia_tree_del
57191 + (&pComponentLink->ProtectionTree, &pLabelEntry->Node) != E_OK)
57193 + zlog_err ("\ncannot delete node from patricia %s %d", __FILE__,
57194 + __LINE__);
57195 + return;
57197 + XFREE (MTYPE_TE, pLabelEntry);
57198 + return;
57200 + zlog_err ("\nLabel is not backuped nor goes to be backuped %s %d", __FILE__,
57201 + __LINE__);
57204 +void
57205 +FrrIngressRelease (PSB_KEY * PSB_KEY)
57207 + FRR_SM_KEY *pFrrSmKey;
57208 + FRR_SM_ENTRY *pFrrSmEntry;
57209 + FRR_INGRESS_ENTRY *pIngressLabelEntry;
57210 + COMPONENT_LINK *pComponentLink;
57211 + RSVP_TUNNEL_PROPERTIES *pTunnel;
57212 + RSVP_LSP_PROPERTIES *pRsvpLsp;
57213 + uns16 SavedLspId = PSB_KEY->sender.Lsp_IdNet;
57214 + IPV4_ADDR SavedSenderIp = PSB_KEY->sender.IPv4TunnelSenderNet;
57215 + zlog_info ("\nInside of FrrIngressRelease...");
57216 + PSB_KEY->sender.Lsp_IdNet = 0;
57217 + PSB_KEY->sender.IPv4TunnelSenderNet = 0;
57218 + if (FindTunnel (PSB_KEY, &pTunnel, ALL_TRUNKS) == TRUE)
57220 + if (((pRsvpLsp =
57221 + FindRsvpLspByLspId (pTunnel, ntohs (SavedLspId))) != NULL)
57222 + && (pRsvpLsp->tunneled == FALSE))
57224 + pFrrSmKey =
57225 + &pRsvpLsp->forw_info.path.BackupForwardingInformation.frr_key;
57226 + if ((pFrrSmEntry = FindFastRerouteSm (pFrrSmKey)) != NULL)
57228 + PSB_KEY->sender.Lsp_IdNet = SavedLspId;
57229 + PSB_KEY->sender.IPv4TunnelSenderNet = SavedSenderIp;
57230 + zlog_info
57231 + ("\nLooking for the label entry on ont hte FRR's tree...");
57232 + if ((pIngressLabelEntry =
57233 + patricia_tree_get (&pFrrSmEntry->ingress_tree,
57234 + (const uns8 *) PSB_KEY)) != NULL)
57236 + if (patricia_tree_del
57237 + (&pFrrSmEntry->ingress_tree,
57238 + &pIngressLabelEntry->Node) != E_OK)
57240 + zlog_err ("\ncannot delete node from patricia %s %d",
57241 + __FILE__, __LINE__);
57242 + return;
57244 + XFREE (MTYPE_TE, pIngressLabelEntry);
57245 + return;
57248 + else
57250 + zlog_err ("\ncannot find FRR SM %x %x %x %s %d",
57251 + pFrrSmKey->merge_node,
57252 + pFrrSmKey->OutIfIndex,
57253 + pFrrSmKey->protected_node, __FILE__, __LINE__);
57254 + return;
57257 + else
57259 + zlog_err ("\ncannot get RSVP LSP by id %x %s %d", SavedLspId,
57260 + __FILE__, __LINE__);
57261 + return;
57264 + else
57266 + zlog_err ("\ncannot find tunnel %x %x %x %s %d",
57267 + PSB_KEY->Session.Dest,
57268 + PSB_KEY->Session.TunnelId,
57269 + PSB_KEY->Session.ExtTunelId, __FILE__, __LINE__);
57270 + return;
57273 + if (rdb_get_component_link (((LTCS_CB *) GetLcbPtr ())->rdb_layer_handle, pFrrSmEntry->frr_key.OutIfIndex, /* SAME FOR NOW!!! */
57274 + pFrrSmEntry->frr_key.OutIfIndex, /* SAME FOR NOW!!! */
57275 + &pComponentLink) != E_OK)
57277 + zlog_err ("\ncannot get component link %s %d", __FILE__, __LINE__);
57278 + return;
57280 + zlog_info ("\nLooking for the label entry on component link's tree...");
57281 + if ((pIngressLabelEntry =
57282 + patricia_tree_get (&pComponentLink->IngressProtectionTree,
57283 + (const uns8 *) PSB_KEY)) != NULL)
57285 + if (patricia_tree_del
57286 + (&pComponentLink->IngressProtectionTree,
57287 + &pIngressLabelEntry->Node) != E_OK)
57289 + zlog_err ("\ncannot delete node from patricia %s %d", __FILE__,
57290 + __LINE__);
57291 + return;
57293 + XFREE (MTYPE_TE, pIngressLabelEntry);
57294 + return;
57296 + zlog_err ("\nLabel is not backuped nor goes to be backuped %s %d", __FILE__,
57297 + __LINE__);
57300 +void
57301 +BypassTunnelFailed (FRR_SM_DATA * pFrrSmData)
57303 + COMPONENT_LINK *pComponentLink;
57304 + FRR_LABEL_ENTRY *pLabelEntry;
57305 + FRR_INGRESS_ENTRY *pIngressLabelEntry;
57306 + unsigned int key = 0;
57307 + PSB_KEY PSB_KEY;
57308 + FRR_SM_ENTRY *pFrrEntry = &pFrrSmData->FrrSmEntry;
57310 + if (rdb_get_component_link (((LTCS_CB *) GetLcbPtr ())->rdb_layer_handle, pFrrEntry->frr_key.OutIfIndex, /* SAME FOR NOW!!! */
57311 + pFrrEntry->frr_key.OutIfIndex, /* SAME FOR NOW!!! */
57312 + &pComponentLink) != E_OK)
57314 + zlog_err ("\ncannot get component link %s %d", __FILE__, __LINE__);
57315 + return E_ERR;
57317 + memset (&PSB_KEY, 0, sizeof (PSB_KEY));
57318 + while ((pIngressLabelEntry =
57319 + patricia_tree_getnext (&pComponentLink->IngressProtectionTree,
57320 + (const uns8 *) &PSB_KEY)) != NULL)
57322 + if (patricia_tree_del
57323 + (&pComponentLink->IngressProtectionTree,
57324 + &pIngressLabelEntry->Node) != E_OK)
57326 + zlog_err ("\ncannot delete a node from patricia %s %d", __FILE__,
57327 + __LINE__);
57329 + else
57331 + if (patricia_tree_add
57332 + (&pFrrEntry->ingress_tree, &pIngressLabelEntry->Node) != E_OK)
57334 + zlog_err ("\ncannot add node to patricia tree %s %d", __FILE__,
57335 + __LINE__);
57338 + PSB_KEY = pIngressLabelEntry->PSB_KEY;
57340 + while ((pLabelEntry =
57341 + patricia_tree_getnext (&pComponentLink->ProtectionTree,
57342 + (const uns8 *) &key)) != NULL)
57344 + if (patricia_tree_del
57345 + (&pComponentLink->ProtectionTree, &pLabelEntry->Node) != E_OK)
57347 + zlog_err ("\ncannot delete a node from patricia %s %d", __FILE__,
57348 + __LINE__);
57350 + else
57352 + if (patricia_tree_add (&pFrrEntry->labels_tree, &pLabelEntry->Node)
57353 + != E_OK)
57355 + zlog_err ("\ncannot add node to patricia tree %s %d", __FILE__,
57356 + __LINE__);
57359 + key = pLabelEntry->Label;
57363 +void
57364 +BypassTunnelRetryExpiry (LTCS_MSG * pMsg)
57366 + FRR_SM_ENTRY *pFrrSmEntry;
57367 + OPEN_RSVP_CRLSP *pOpenLspParams;
57368 + PSB_KEY PSB_KEY;
57369 + SM_CALL_T *pCall;
57370 + SM_T *pSm;
57372 + if ((pFrrSmEntry =
57373 + FindFastRerouteSm (&pMsg->info.bypass_retry_expiry.key)) != NULL)
57375 + pSm = pFrrSmEntry->sm_handle;
57376 + if ((pOpenLspParams =
57377 + XMALLOC (MTYPE_TE, sizeof (OPEN_RSVP_CRLSP))) == NULL)
57379 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
57380 + /* Do some clean up here */
57381 + return;
57383 + pOpenLspParams->tunnel_id = pFrrSmEntry->BypassTunnelId;
57384 + pOpenLspParams->ErHops2Exclude[0] = pFrrSmEntry->frr_key.protected_node;
57385 + pOpenLspParams->ErHops2Exclude[1] =
57386 + pFrrSmEntry->frr_key.prohibited_penultimate_node;
57387 + pOpenLspParams->dest_ip = pFrrSmEntry->frr_key.merge_node;
57388 + pOpenLspParams->src_ip = rdb_get_router_id ();
57389 + pOpenLspParams->BW = 0;
57390 + pOpenLspParams->Flags = RSVP_SESS_ATTRIBUTE_FLAG_SE_STYLE;
57391 + pOpenLspParams->SetupPriority = 4;
57392 + pOpenLspParams->HoldPriority = 4;
57394 + if ((pCall =
57395 + lsp_sm_sync_invoke (pSm, pOpenLspParams,
57396 + INGRESS_LSP_REQUEST_EVENT)) == NULL)
57398 + zlog_err ("\ncan not invoke sm %s %d", __FILE__, __LINE__);
57400 + else
57401 + sm_call (pCall);
57403 + else
57405 + zlog_err ("\ncannot get FRR SM entry %x %x %x %s %d",
57406 + pMsg->info.bypass_retry_expiry.key.merge_node,
57407 + pMsg->info.bypass_retry_expiry.key.OutIfIndex,
57408 + pMsg->info.bypass_retry_expiry.key.protected_node,
57409 + __FILE__, __LINE__);
57413 +uns32
57414 +InformRsvpAboutFrr (PSB_KEY * PSB_KEY,
57415 + V_CARD_ID to_card,
57416 + uns32 to_if,
57417 + uns32 NewOutIf, V_CARD_ID NewVcardId, IPV4_ADDR first_hop)
57419 + LTCS_MSG *pMsg;
57420 + if ((pMsg = dmsg_create (GetLcbPtr (), LTCS_EVENT_FRR_INFO_SET)) == NULL)
57422 + zlog_info ("\ncannot create message %s %d", __FILE__, __LINE__);
57423 + return E_ERR;
57425 + zlog_info ("\ninside of InformRsvpAboutFrr %x %x %x %x %x",
57426 + PSB_KEY->Session.Dest,
57427 + PSB_KEY->Session.TunnelId,
57428 + PSB_KEY->Session.ExtTunelId,
57429 + PSB_KEY->sender.Lsp_IdNet, PSB_KEY->sender.IPv4TunnelSenderNet);
57430 + pMsg->info.frr_data_set.PSB_KEY = *PSB_KEY;
57431 + pMsg->info.frr_data_set.IfIndex = to_if;
57432 + pMsg->info.frr_data_set.BackupOutIf = NewOutIf;
57433 + pMsg->info.frr_data_set.BackupVcardId = NewVcardId;
57434 + pMsg->info.frr_data_set.MergeNodeIp = first_hop;
57435 + if (svc_send_msg (pMsg, to_card, MDS_USR_CONSOLE_SVC) != E_OK)
57437 + zlog_info ("\nFatal: can not send mds message %s %d", __FILE__,
57438 + __LINE__);
57439 + return E_ERR;
57441 + dmsg_release (pMsg);
57442 + return E_OK;
57445 +void
57446 +FastReRouteSmDestroy (SM_T * pSm)
57448 + sm_gen_free (pSm);
57451 +void
57452 +FrrSmDump ()
57454 + FRR_SM_ENTRY *pFrrSmEntry;
57455 + FRR_SM_KEY frr_key;
57456 + FRR_INGRESS_ENTRY *pIngressEntry;
57457 + FRR_LABEL_ENTRY *pLabelEntry;
57458 + PSB_KEY PSB_KEY;
57459 + unsigned int label;
57460 + SM_T *pSm;
57461 + FRR_SM_DATA *pFrrSmData;
57462 + COMPONENT_LINK *pComponentLink;
57464 + memset (&frr_key, 0, sizeof (FRR_SM_KEY));
57466 + while ((pFrrSmEntry =
57467 + patricia_tree_getnext (&FastReRouteSmTree,
57468 + (const uns8 *) &frr_key)) != NULL)
57470 + pSm = pFrrSmEntry->sm_handle;
57471 + pFrrSmData = pSm->data;
57472 + zlog_info
57473 + ("\nFRR SM protected node: %x I/F %x merge node %x tunnel ID %x BypassLabel %x BypasIfIndex %x",
57474 + pFrrSmEntry->frr_key.protected_node, pFrrSmEntry->frr_key.OutIfIndex,
57475 + pFrrSmEntry->frr_key.merge_node, pFrrSmEntry->BypassTunnelId,
57476 + pFrrSmData->BypassTunnelsLabel, pFrrSmData->BackupOutIf);
57477 + label = 0;
57478 + zlog_info ("\nNot completed Label (LSR) entries:");
57479 + while ((pLabelEntry =
57480 + patricia_tree_getnext (&pFrrSmEntry->labels_tree,
57481 + (const uns8 *) &label)) != NULL)
57483 + zlog_info
57484 + ("\nLabel#%x valid %x merge node label %x Out I/F %x Bypass label %x",
57485 + pLabelEntry->Label,
57486 + PlatformWideLabelSpace[pLabelEntry->Label -
57487 + 1].BackupForwardingInformation.
57488 + MergeNodeLabelValid,
57489 + PlatformWideLabelSpace[pLabelEntry->Label -
57490 + 1].BackupForwardingInformation.
57491 + MergeNodeLabel,
57492 + PlatformWideLabelSpace[pLabelEntry->Label -
57493 + 1].BackupForwardingInformation.OutIf,
57494 + PlatformWideLabelSpace[pLabelEntry->Label -
57495 + 1].BackupForwardingInformation.
57496 + BypassTunnelsLabel);
57497 + label = pLabelEntry->Label;
57499 + memset (&PSB_KEY, 0, sizeof (PSB_KEY));
57500 + zlog_info ("\nNot completed Ingress entries:");
57501 + while ((pIngressEntry =
57502 + patricia_tree_getnext (&pFrrSmEntry->ingress_tree,
57503 + (const uns8 *) &PSB_KEY)) != NULL)
57505 + RSVP_TUNNEL_PROPERTIES *pTunnel;
57506 + RSVP_LSP_PROPERTIES *pRsvpLsp;
57507 + PSB_KEY rkey;
57509 + zlog_info ("\nDEST#%x Tunnel#%x Source#%x LSP ID#%x",
57510 + pIngressEntry->PSB_KEY.Session.Dest,
57511 + pIngressEntry->PSB_KEY.Session.TunnelId,
57512 + pIngressEntry->PSB_KEY.Session.ExtTunelId,
57513 + pIngressEntry->PSB_KEY.sender.Lsp_IdNet);
57515 + memset (&rkey, 0, sizeof (PSB_KEY));
57516 + rkey = pIngressEntry->PSB_KEY;
57517 + rkey.sender.Lsp_IdNet = 0;
57518 + if (FindTunnel (&rkey, &pTunnel, ALL_TRUNKS) == TRUE)
57520 + if ((pRsvpLsp =
57521 + FindRsvpLspByLspId (pTunnel,
57522 + pIngressEntry->PSB_KEY.sender.
57523 + Lsp_IdNet)) != NULL)
57525 + zlog_info
57526 + ("\n Bypass label %x Merge node label valid %x Merge node label %x Out I/F %x",
57527 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
57528 + BypassTunnelsLabel,
57529 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
57530 + MergeNodeLabelValid,
57531 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
57532 + MergeNodeLabel,
57533 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
57534 + OutIf);
57537 + PSB_KEY = pIngressEntry->PSB_KEY;
57540 + if (rdb_get_component_link (((LTCS_CB *) GetLcbPtr ())->rdb_layer_handle, pFrrSmEntry->frr_key.OutIfIndex, /* SAME FOR NOW!!! */
57541 + pFrrSmEntry->frr_key.OutIfIndex, /* SAME FOR NOW!!! */
57542 + &pComponentLink) != E_OK)
57544 + zlog_err ("\ncannot get component link %s %d", __FILE__, __LINE__);
57545 + frr_key = pFrrSmEntry->frr_key;
57546 + continue;
57548 + zlog_info ("\nCompleted Label (LSR) entries:");
57549 + while ((pLabelEntry =
57550 + patricia_tree_getnext (&pComponentLink->ProtectionTree,
57551 + (const uns8 *) &label)) != NULL)
57553 + zlog_info
57554 + ("\nLabel#%x valid %x merge node label %x Out I/F %x Bypass label %x",
57555 + pLabelEntry->Label,
57556 + PlatformWideLabelSpace[pLabelEntry->Label -
57557 + 1].BackupForwardingInformation.
57558 + MergeNodeLabelValid,
57559 + PlatformWideLabelSpace[pLabelEntry->Label -
57560 + 1].BackupForwardingInformation.
57561 + MergeNodeLabel,
57562 + PlatformWideLabelSpace[pLabelEntry->Label -
57563 + 1].BackupForwardingInformation.OutIf,
57564 + PlatformWideLabelSpace[pLabelEntry->Label -
57565 + 1].BackupForwardingInformation.
57566 + BypassTunnelsLabel);
57567 + label = pLabelEntry->Label;
57569 + memset (&PSB_KEY, 0, sizeof (PSB_KEY));
57570 + zlog_info ("\nCompleted Ingress entries:");
57571 + while ((pIngressEntry =
57572 + patricia_tree_getnext (&pComponentLink->IngressProtectionTree,
57573 + (const uns8 *) &PSB_KEY)) != NULL)
57575 + RSVP_TUNNEL_PROPERTIES *pTunnel;
57576 + RSVP_LSP_PROPERTIES *pRsvpLsp;
57577 + PSB_KEY rkey;
57579 + zlog_info ("\nDEST#%x Tunnel#%x Source#%x LSP ID#%x",
57580 + pIngressEntry->PSB_KEY.Session.Dest,
57581 + pIngressEntry->PSB_KEY.Session.TunnelId,
57582 + pIngressEntry->PSB_KEY.Session.ExtTunelId,
57583 + pIngressEntry->PSB_KEY.sender.Lsp_IdNet);
57584 + memset (&rkey, 0, sizeof (PSB_KEY));
57585 + rkey = pIngressEntry->PSB_KEY;
57586 + rkey.sender.Lsp_IdNet = 0;
57587 + if (FindTunnel (&rkey, &pTunnel, ALL_TRUNKS) == TRUE)
57589 + if ((pRsvpLsp =
57590 + FindRsvpLspByLspId (pTunnel,
57591 + pIngressEntry->PSB_KEY.sender.
57592 + Lsp_IdNet)) != NULL)
57594 + zlog_info
57595 + ("\n Bypass label %x Merge node label valid %x Merge node label %x Out I/F %x",
57596 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
57597 + BypassTunnelsLabel,
57598 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
57599 + MergeNodeLabelValid,
57600 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
57601 + MergeNodeLabel,
57602 + pRsvpLsp->forw_info.path.BackupForwardingInformation.
57603 + OutIf);
57606 + PSB_KEY = pIngressEntry->PSB_KEY;
57608 + frr_key = pFrrSmEntry->frr_key;
57611 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_frr.h quagga-mpls/rsvpd/te_frr.h
57612 --- quagga/rsvpd/te_frr.h 1969-12-31 18:00:00.000000000 -0600
57613 +++ quagga-mpls/rsvpd/te_frr.h 2007-06-18 23:55:58.000000000 -0500
57614 @@ -0,0 +1,52 @@
57615 +#ifndef __FAST_REROUTE_H_
57616 +#define __FAST_REROUTE_H_
57618 +typedef enum
57620 + FAST_REROUTE_SM_UP_STATE = INIT_STATE + 1,
57621 + FAST_REROUTE_RETRY_STATE,
57622 + FAST_REROUTE_SM_MAX_STATE
57623 +} FAST_REROUTE_SM_STATE_E;
57625 +typedef struct
57627 + PATRICIA_NODE Node;
57628 + unsigned int Label;
57629 +} FRR_LABEL_ENTRY;
57631 +typedef struct
57633 + PATRICIA_NODE Node;
57634 + PSB_KEY PsbKey;
57635 +} FRR_INGRESS_ENTRY;
57637 +typedef struct
57639 + FRR_SM_KEY frr_key;
57640 + PSB_KEY PsbKey;
57641 + unsigned int Label;
57642 + IPV4_ADDR MergeNode;
57643 +} FRR_SM_CALL;
57645 +typedef struct
57647 + PATRICIA_NODE Node;
57648 + FRR_SM_KEY frr_key;
57649 + uns32 sm_handle;
57650 + PATRICIA_TREE labels_tree;
57651 + PATRICIA_TREE ingress_tree;
57652 + uns16 BypassTunnelId;
57653 + TE_TMR bypass_retry_timer;
57654 +} FRR_SM_ENTRY;
57656 +typedef struct
57658 + FRR_SM_ENTRY FrrSmEntry;
57659 + unsigned int BypassTunnelsLabel;
57660 + uns32 BackupOutIf;
57661 + //V_CARD_ID card;
57662 +} FRR_SM_DATA;
57664 +SM_CALL_T *fast_reroute_sm_handler (HANDLE sm_handle, SM_EVENT_T * sm_data);
57666 +#endif
57667 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te.h quagga-mpls/rsvpd/te.h
57668 --- quagga/rsvpd/te.h 1969-12-31 18:00:00.000000000 -0600
57669 +++ quagga-mpls/rsvpd/te.h 2007-07-03 00:41:30.000000000 -0500
57670 @@ -0,0 +1,45 @@
57671 +#ifndef _TE_INCLUDES_H_
57672 +#define _TE_INCLUDES_H_
57674 +#include <stdio.h>
57675 +#include <stdlib.h>
57676 +#include <string.h>
57677 +#include <sys/types.h>
57678 +#include <sys/socket.h>
57679 +#include <sys/ioctl.h>
57680 +#include <net/if.h>
57681 +#include <netinet/in.h>
57682 +#include <netinet/ip.h>
57683 +#include <unistd.h>
57684 +#include <time.h>
57685 +#include <sys/time.h>
57686 +#include <sys/file.h>
57687 +#include <sys/fcntl.h>
57688 +#include <sys/ioctl.h>
57689 +#include <sys/uio.h>
57690 +#include <ctype.h>
57691 +#include <math.h>
57692 +#include <errno.h>
57693 +#include <zebra.h>
57694 +#include "thread.h"
57695 +#include "vty.h"
57696 +#include "command.h"
57697 +#include "log.h"
57698 +#include "memory.h"
57699 +#include "patricia.h"
57700 +#include "zclient.h"
57702 +#include "general.h"
57703 +#include "messages.h"
57704 +#include "rsvp_packet.h"
57705 +#include "te_lib.h"
57706 +#include "te_rdb.h"
57707 +#include "te_api.h"
57708 +#include "te_common.h"
57709 +#include "te_lsp.h"
57710 +#include "te_tr.h"
57711 +#include "te_crr.h"
57712 +#include "te_frr.h"
57713 +#include "te_bw_man.h"
57715 +#endif
57716 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_lib.c quagga-mpls/rsvpd/te_lib.c
57717 --- quagga/rsvpd/te_lib.c 1969-12-31 18:00:00.000000000 -0600
57718 +++ quagga-mpls/rsvpd/te_lib.c 2007-06-19 00:05:00.000000000 -0500
57719 @@ -0,0 +1,270 @@
57720 +/* Module: te_config_data_plane.c
57721 + Contains: TE application data plane configuration
57722 + functions. Called when an tunnel is established.
57723 + For the transit tunnels (LSR) - when corresponding
57724 + RESV received.
57725 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
57726 + */
57727 +#include "te.h"
57729 +void
57730 +mplsTePolicy (char *PolicyName, char *LabelEntryKey, int opcode)
57734 +void
57735 +mplsTeInOutLabel (unsigned int AllocatedLabel,
57736 + unsigned int ReceivedLabelMapping, unsigned int OutIfIndex)
57740 +/* A data plane configuration for the Ingress tunnels (only outgoing label) */
57741 +void
57742 +mplsTeOutLabel (int *OutLabels, int OutLabelsCount, char *key, int NextHop,
57743 + int opcode)
57747 +/* Module: label_man.c
57748 + Contains: TE application label manager
57749 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
57750 + */
57752 +extern PATRICIA_TREE PlatformWideFreeLabels;
57753 +extern PATRICIA_TREE LineCard2LabelsTree;
57755 +LABEL_ENTRY PlatformWideLabelSpace[LABEL_SPACE_SIZE];
57757 +uns32
57758 +LabelAllocate (unsigned int *Label, LABEL_POLICY_E policy, PSB_KEY * pKey,
57759 + uns32 IfIndex)
57761 + uns8 key = 0;
57762 + LABEL_ENTRY *p_label_entry;
57763 + if ((p_label_entry = (LABEL_ENTRY *)
57764 + patricia_tree_getnext (&PlatformWideFreeLabels,
57765 + (const uns8 *) &key)) == NULL)
57767 + zlog_err ("\ncannot allocate label %s %d", __FILE__, __LINE__);
57768 + return E_ERR;
57770 + if (((p_label_entry->label % 2) && (policy == EVEN_LABELS)) ||
57771 + ((!(p_label_entry->label % 2)) && (policy == ODD_LABELS)))
57773 + key = p_label_entry->label;
57774 + if ((p_label_entry = (LABEL_ENTRY *)
57775 + patricia_tree_getnext (&PlatformWideFreeLabels,
57776 + (const uns8 *) &key)) == NULL)
57778 + zlog_err ("\ncannot allocate label %s %d", __FILE__, __LINE__);
57779 + return E_ERR;
57782 + if (patricia_tree_del (&PlatformWideFreeLabels, &p_label_entry->Node) !=
57783 + E_OK)
57785 + zlog_err ("\nfatal: cannot remove entry from patricia tree %s %d",
57786 + __FILE__, __LINE__);
57787 + return E_ERR;
57790 + p_label_entry->IfIndex = IfIndex; /* needed for FRR */
57792 + *Label = p_label_entry->label;
57793 + zlog_info ("\nLabel allocation performed: label %x \
57794 +dest %x tunnel id %x ext tunnel id %x lsp id %x ", *Label, pKey->Session.Dest, pKey->Session.TunnelId, pKey->Session.ExtTunelId, pKey->SenderTemplate.LspId);
57795 + return E_OK;
57798 +uns32
57799 +TE_RSVPTE_API_LabelRelease (TE_API_MSG * dmsg)
57801 + LABEL_ENTRY *p_label_entry;
57802 +#ifdef FRR_SM_DEFINED
57803 + FrrLabelRelease (dmsg->u.LabelRelease.Label);
57804 +#endif
57805 + if ((dmsg->u.LabelRelease.Label <= 0)
57806 + || (dmsg->u.LabelRelease.Label >= LABEL_SPACE_SIZE))
57808 + zlog_err ("Invalid label %x %s %d", dmsg->u.LabelRelease.Label,
57809 + __FILE__, __LINE__);
57810 + return E_ERR;
57812 + p_label_entry = &PlatformWideLabelSpace[dmsg->u.LabelRelease.Label - 1];
57814 + if (patricia_tree_add (&PlatformWideFreeLabels, &p_label_entry->Node) !=
57815 + E_OK)
57817 + zlog_err ("\ncannot return label %s %d", __FILE__, __LINE__);
57818 + return E_ERR;
57820 + return E_OK;
57824 +int
57825 +LSRLabelMappingReceived (unsigned int AllocatedLabel,
57826 + unsigned int ReceivedLabelMapping,
57827 + unsigned int OutIfIndex)
57829 + if ((AllocatedLabel >= LABEL_SPACE_SIZE) || (AllocatedLabel < 1))
57831 + zlog_err ("\ninvalid AllocatedLabel (out of range) %s %d", __FILE__,
57832 + __LINE__);
57833 + return E_ERR;
57835 + if (patricia_tree_get
57836 + (&PlatformWideFreeLabels, (const uns8 *) &AllocatedLabel) != NULL)
57838 + zlog_err ("\nAllocated Label is not really allocated %s %d...",
57839 + __FILE__, __LINE__);
57840 + return E_ERR;
57842 + PlatformWideLabelSpace[AllocatedLabel - 1].ReceivedOutLabel =
57843 + ReceivedLabelMapping;
57844 + PlatformWideLabelSpace[AllocatedLabel - 1].OutIf = OutIfIndex;
57845 + mplsTeInOutLabel (AllocatedLabel, ReceivedLabelMapping, OutIfIndex);
57846 + return E_OK;
57849 +void
57850 +IngressLabelMappingReceived (unsigned int ReceivedLabelMapping,
57851 + unsigned int OutIfIndex, PSB_KEY * pKey)
57853 +#if DATA_PLANE
57855 + char key[23];
57856 + IPV4_ADDR next_hop = 0;
57857 + RSVP_TUNNEL_PROPERTIES *pTunnel;
57858 + RSVP_LSP_PROPERTIES *pRsvpLsp;
57859 + USER_LSP *pUserLsp;
57860 + if (FindTunnel (pKey, &pTunnel, ALL_TRUNKS) != TRUE)
57862 + return;
57864 + pUserLsp = UserLspGet (pTunnel->UserLspName);
57865 + if ((pUserLsp) && (pUserLsp->pUserLspTunnels == NULL))
57867 + return;
57869 +/* commented in order to configure the label of the backup LSP in the data plane
57870 + if((pUserLsp->pUserLspTunnels->TunnelId != pTunnel->TunnelId)&&
57871 + (pUserLsp->BackupTunnelId != pTunnel->TunnelId))
57873 + return;
57874 + }*/
57875 + if ((pRsvpLsp = GetWorkingRsvpLsp (pTunnel)) == NULL)
57877 + return;
57879 + if ((pRsvpLsp->tunneled == FALSE)
57880 + && (pRsvpLsp->forw_info.path.HopCount != 0))
57882 + next_hop = pRsvpLsp->forw_info.path.pErHopsList[0];
57884 + sprintf (key, "%x%d%x%d", pKey->Session.Dest, pTunnel->TunnelId,
57885 + pKey->Session.ExtTunelId, pRsvpLsp->LspId);
57886 + zlog_info ("create label %x next hop %x \nkey %s\nUserLspName %s\n",
57887 + pRsvpLsp->Label, next_hop, key, pTunnel->UserLspName);
57888 + mplsTeOutLabel (&pRsvpLsp->Label, 1, key, next_hop, 1);
57889 + if ((pUserLsp != NULL) && (pUserLsp->params.PolicyName[0] != '\0'))
57891 + if ((pUserLsp->pUserLspTunnels->TunnelId == pTunnel->TunnelId) &&
57892 + (pUserLsp->BackupTunnelId))
57894 + char key1[23];
57895 + PSB_KEY PsbKey;
57897 + memset (&PsbKey, 0, sizeof (PSB_KEY));
57898 + PsbKey.Session.Dest = pKey->Session.Dest;
57899 + PsbKey.Session.ExtTunelId = pKey->Session.ExtTunelId;
57900 + PsbKey.Session.TunnelId = pUserLsp->BackupTunnelId;
57901 + if (FindTunnel (&PsbKey, &pTunnel, ALL_TRUNKS) != TRUE)
57903 + return;
57905 + if ((pRsvpLsp = GetWorkingRsvpLsp (pTunnel)) == NULL)
57907 + return;
57909 + sprintf (key1, "%x%d%x%d", pKey->Session.Dest, pTunnel->TunnelId,
57910 + pKey->Session.ExtTunelId, pRsvpLsp->LspId);
57911 + mplsTePolicy (pUserLsp->params.PolicyName, key1, 0);
57912 + pUserLsp->BackupTunnelId = 0;
57914 + zlog_info ("PolicyName %s", pUserLsp->params.PolicyName);
57915 + mplsTePolicy (pUserLsp->params.PolicyName, key, 1);
57918 +#endif
57919 + return;
57922 +void
57923 +AssignedLabelsDump ()
57925 + uns32 key = 0, i;
57926 + LABEL_ENTRY *p_label_entry;
57927 + for (i = 0; i < LABEL_SPACE_SIZE; i++)
57929 + key = i + 1;
57930 + if ((p_label_entry = (LABEL_ENTRY *)
57931 + patricia_tree_get (&PlatformWideFreeLabels,
57932 + (const uns8 *) &key)) != NULL)
57933 + zlog_info ("\nlabel %x", p_label_entry->label);
57935 + return;
57939 +/* Module: lsr.c
57940 + Contains: TE application transit RESV message processing
57941 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
57942 + */
57946 +void
57947 +TE_RSVPTE_API_TransitResv (TE_API_MSG * dmsg)
57949 + PSB_KEY key;
57950 + int i;
57951 + float MaximumPossibleBW = 0;
57952 + memset (&key, 0, sizeof (PSB_KEY));
57953 + key.Session = dmsg->u.ResvNotification.RsbKey.Session;
57954 + if (TE_RSVPTE_API_DoAllocation (&key,
57955 + dmsg->u.ResvNotification.u.FilterDataSE.
57956 + IfIndex /* temporary */ ,
57957 + dmsg->u.ResvNotification.u.FilterDataSE.
57958 + IfIndex,
57959 + dmsg->u.ResvNotification.u.FilterDataSE.BW,
57960 + dmsg->u.ResvNotification.u.FilterDataSE.
57961 + SetupPrio,
57962 + dmsg->u.ResvNotification.u.FilterDataSE.
57963 + HoldPrio, &MaximumPossibleBW) != E_OK)
57965 + zlog_info ("\nBW allocation failed %s %d", __FILE__, __LINE__);
57966 + dmsg->u.ResvNotification.u.FilterDataSE.BW = MaximumPossibleBW;
57967 + dmsg->u.ResvNotification.rc = FALSE;
57969 + else
57971 + zlog_info ("BW allocation succeeded. Updating LSR's table...");
57972 + for (i = 0;
57973 + i < dmsg->u.ResvNotification.u.FilterDataSE.FilterSpecNumber; i++)
57975 + if (LSRLabelMappingReceived
57976 + (dmsg->u.ResvNotification.u.FilterDataSE.FilterDataArraySE[i].
57977 + AllocatedLabel,
57978 + dmsg->u.ResvNotification.u.FilterDataSE.FilterDataArraySE[i].
57979 + ReceivedLabel,
57980 + dmsg->u.ResvNotification.u.FilterDataSE.IfIndex) != E_OK)
57984 + dmsg->u.ResvNotification.rc = TRUE;
57986 + zlog_info ("Sending reply to TE");
57987 + rsvp_send_msg (dmsg, sizeof (TE_API_MSG));
57988 + return;
57990 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_lib.h quagga-mpls/rsvpd/te_lib.h
57991 --- quagga/rsvpd/te_lib.h 1969-12-31 18:00:00.000000000 -0600
57992 +++ quagga-mpls/rsvpd/te_lib.h 2007-07-03 00:39:34.000000000 -0500
57993 @@ -0,0 +1,44 @@
57994 +#ifndef __TE_CONFIG_DATA_PLANE_H_
57995 +#define __TE_CONFIG_DATA_PLANE_H_
57997 +void mplsTePolicy (char *PolicyName, char *LabelEntryKey, int opcode);
57998 +void mplsTeInOutLabel (unsigned int AllocatedLabel,
57999 + unsigned int ReceivedLabelMapping,
58000 + unsigned int OutIfIndex);
58001 +void mplsTeOutLabel (int *OutLabels, int OutLabelsCount, char *key,
58002 + int NextHop, int opcode);
58004 +#endif
58006 +#ifndef __LABEL_MAN_H_
58007 +#define __LABEL_MAN_H_
58010 +typedef enum
58012 + ODD_LABELS,
58013 + EVEN_LABELS,
58014 + ALL_LABELS,
58015 + MAX_LABELS
58016 +} LABEL_POLICY_E;
58018 +#define LABEL_SPACE_SIZE 0x2000
58020 +uns32 TE_RSVPTE_API_LabelRelease (TE_API_MSG * dmsg);
58021 +uns32 LabelAllocate (unsigned int *Label,
58022 + LABEL_POLICY_E policy, PSB_KEY * pKey, uns32 IfIndex);
58023 +void IngressLabelMappingReceived (unsigned int ReceivedLabelMapping,
58024 + unsigned int OutIfIndex, PSB_KEY * pKey);
58026 +int LSRLabelMappingReceived (unsigned int AllocatedLabel,
58027 + unsigned int ReceivedLabelMapping,
58028 + unsigned int OutIfIndex);
58030 +#endif
58032 +#ifndef __LSR_H__
58033 +#define __LSR_H__
58035 +void TE_RSVPTE_API_TransitResv (TE_API_MSG * dmsg);
58037 +#endif
58038 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_lsp.c quagga-mpls/rsvpd/te_lsp.c
58039 --- quagga/rsvpd/te_lsp.c 1969-12-31 18:00:00.000000000 -0600
58040 +++ quagga-mpls/rsvpd/te_lsp.c 2007-06-19 00:08:12.000000000 -0500
58041 @@ -0,0 +1,4372 @@
58042 +/* Module: lsp_sm.c
58043 + Contains: TE application LSP (tunnel) state machine
58044 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
58045 + */
58046 +#include "te.h"
58047 +#include "te_cspf.h"
58049 +typedef enum
58051 + WORKING_LSP_FAILED,
58052 + NEW_LSP_FAILED
58053 +}RECOVERY_TYPE_E;
58055 +void LspSmDestroy(SM_T *pSm);
58056 +void UserLspDestroy(USER_LSP *pUserLsp);
58057 +E_RC SetErHopList(STATIC_PATH *pStaticPath,ER_HOP **ppErHopsList);
58058 +SM_CALL_T *ProcessPrimaryLsp(USER_LSP *pCurrentUserLsp,
58059 + USER_LSP *pUserLsp,
58060 + SM_T *pSm,
58061 + char *PrimaryLspPathName);
58062 +RSVP_TUNNEL_PROPERTIES *GetSecondaryTunnel2Reroute(USER_LSP *pUserLsp,
58063 + USER_LSP *pCurrentUserLsp);
58064 +SM_CALL_T *ProcessSecondaryPaths(USER_LSP *pCurrentUserLsp,
58065 + USER_LSP *pUserLsp,
58066 + SM_T *pSm,
58067 + char *PrimaryLspPathName,
58068 + BOOL PrimaryLspOperation);
58069 +uns32 StartAdaptivityTimer(uns32 optimize_timer,
58070 + RSVP_TUNNEL_PROPERTIES *pTunnel);
58072 +void StopAdaptivityTimer(RSVP_TUNNEL_PROPERTIES *pTunnel);
58073 +uns32 StartLspSetupTimer(RSVP_TUNNEL_PROPERTIES *pTunnel);
58074 +void StopLspSetupTimer(RSVP_TUNNEL_PROPERTIES *pTunnel);
58075 +uns32 StartLspSetupRetryTimer(uns32 retry_timer,uns32 *retry_count,RSVP_TUNNEL_PROPERTIES *pTunnel);
58076 +void StopLspSetupRetryTimer(RSVP_TUNNEL_PROPERTIES *pTunnel);
58077 +SM_CALL_T *LspSetupExpiry(PSB_KEY *PsbKey,SM_T *pSm);
58078 +SM_CALL_T *AdaptivityExpiry(PSB_KEY *PsbKey,SM_T *pSm);
58079 +SM_CALL_T *LspSetupRetryExpiry(PSB_KEY *PsbKey,SM_T *pSm);
58080 +SM_CALL_T *CspfRetryExpiry(PSB_KEY *PsbKey,SM_T *pSm);
58081 +void TearDownAndRemoveSecondary(USER_LSP *pCurrentUserLsp,char *PathName);
58082 +void CalculateUnneededPathAndTearDown(USER_LSP *pUserLsp,USER_LSP *pCurrentUserLsp);
58083 +SM_CALL_T *PrepareAndIssueCrResolutionRequest(INGRESS_API *pOpenLspParams,
58084 + uns32 AvoidHopNumber,
58085 + IPV4_ADDR *AvoidHopsArray,
58086 + RSVP_TUNNEL_PROPERTIES *pTunnel,
58087 + SM_T *pSm,
58088 + LSP_PATH_SHARED_PARAMS *pParams);
58089 +SM_CALL_T *LspRequest(INGRESS_API *pOpenLspParams,
58090 + uns32 ExcludeHopNumber,
58091 + IPV4_ADDR *ExcludeHopsArray,
58092 + SM_T *pSm,
58093 + RSVP_TUNNEL_PROPERTIES **ppTunnel,
58094 + BOOL ForceCrResolution,
58095 + LSP_PATH_SHARED_PARAMS *pParams);
58097 +BOOL NewRsvpLspRequired(RSVP_TUNNEL_PROPERTIES *pTunnel,INGRESS_API *pOpenLspParams);
58098 +RSVP_LSP_PROPERTIES *FindRsvpLspPathWithBW(RSVP_TUNNEL_PROPERTIES *pTunnel,float BW);
58099 +void NotifySatisfiedRequests(RSVP_TUNNEL_PROPERTIES *pTunnel);
58100 +void NotifyFailedRequests(RSVP_TUNNEL_PROPERTIES *pTunnel);
58101 +uns16 NewRsvpLspId(RSVP_TUNNEL_PROPERTIES *pTunnel);
58102 +uns32 CopyRsvpLspPath(RSVP_LSP_PROPERTIES *pRsvpLsp,INGRESS_API *pOpenRsvpLsp);
58103 +RSVP_LSP_PROPERTIES *GetWorkingRsvpLsp(RSVP_TUNNEL_PROPERTIES *pTunnel);
58104 +uns32 CopyWorkingPath(RSVP_LSP_PROPERTIES *pDestRsvpLsp,RSVP_LSP_PROPERTIES *pSourceRsvpLsp);
58105 +BOOL IdenticalRsvpLspExists(RSVP_TUNNEL_PROPERTIES *pTunnel,RSVP_LSP_PROPERTIES *pThisRsvpLsp,uns16 *LspDiffPathSameParams);
58106 +void UpdatePathBW(RSVP_TUNNEL_PROPERTIES *pTunnel,RSVP_LSP_PROPERTIES *pCurrentRsvpLsp,IPV4_ADDR dest);
58107 +uns32 CreateAndInvokeRsvpLsp(RSVP_TUNNEL_PROPERTIES *pTunnel,
58108 + RSVP_LSP_PROPERTIES *pRsvpLsp2TakePath,
58109 + BOOL tunneled,
58110 + PSB_KEY *PsbKey);
58111 +uns32 RsvpTunnelTearDown(RSVP_TUNNEL_PROPERTIES *pTunnel,IPV4_ADDR dest,IPV4_ADDR source);
58112 +void RemoveRsvpLsp(RSVP_TUNNEL_PROPERTIES *pTunnel,uns16 LspId,IPV4_ADDR dest,IPV4_ADDR source);
58113 +RSVP_LSP_PROPERTIES *FindRsvpLspByLspId(RSVP_TUNNEL_PROPERTIES *pTunnel,uns16 LspId);
58114 +void FindClosestRsvpLsp(RSVP_TUNNEL_PROPERTIES *pTunnel,
58115 + SETUP_COMPLETE *setup_complete,
58116 + float *BW,
58117 + uns16 *LspId);
58118 +SM_CALL_T *DetermineWorkingLspAndTearUnneeded(RSVP_TUNNEL_PROPERTIES *pTunnel,
58119 + float BW,
58120 + uns16 LspId,
58121 + IPV4_ADDR dest,
58122 + IPV4_ADDR source,
58123 + SM_T *pSm);
58124 +RSVP_LSP_PROPERTIES *GetRsvpLspMaxBW(RSVP_TUNNEL_PROPERTIES *pTunnel,uns16 LspId,float MaxBw);
58125 +IPV4_ADDR GetLastErHop(RSVP_LSP_PROPERTIES *pRsvpLsp);
58126 +BOOL IsPathEqual(PATH *pPath,IPV4_ADDR *IpAddrList);
58127 +PATH *FindRsvpLspPath(PATH_L_LIST *pPaths,RSVP_LSP_PROPERTIES *pRsvpLsp);
58128 +uns16 GetSecondaryUserLspId(RSVP_TUNNEL_PROPERTIES *pTunnel,char *pSecondaryPathName);
58129 +uns32 AddSecondaryTunnel(USER_LSP *pUserLsp,RSVP_TUNNEL_PROPERTIES *pSecondaryTunnel);
58130 +void CleanSecodaryPaths(USER_LSP *pUserLsp);
58131 +void CleanUserLsp(USER_LSP *pUserLsp);
58132 +void CopyUserLsp(USER_LSP *pDestLsp,USER_LSP *pSrcLsp);
58133 +LSP_PATH_SHARED_PARAMS *PathParamsGet(USER_LSP *pUserLsp,char *PathName,uns8 IsPrimary);
58134 +RSVP_TUNNEL_PROPERTIES *StaticPathIsUsed(USER_LSP *pUserLsp,char *PathName);
58135 +SM_CALL_T *UserPrimaryLspRecovery(RSVP_TUNNEL_PROPERTIES *pTunnel,SM_T *pSm,RECOVERY_TYPE_E recovery_type,IPV4_ADDR exclude_node);
58136 +SM_CALL_T *UserSecondaryLspRecovery(RSVP_TUNNEL_PROPERTIES *pTunnel,SM_T *pSm,IPV4_ADDR exclude_node);
58137 +SM_CALL_T *UserLspFailed(RSVP_TUNNEL_PROPERTIES *pTunnel,SM_T *pSm,IPV4_ADDR exclude_node);
58138 +uns32 GetTunnelHops(RSVP_TUNNEL_PROPERTIES *pTunnel,uns32 *ErHopNumber,IPV4_ADDR **ppErHops);
58139 +BOOL TunnelsHaveSharedErHops(IPV4_ADDR *pFirstArray,
58140 + uns32 FirstArraySize,
58141 + IPV4_ADDR *pSecondArray,
58142 + uns32 SecondArraySize);
58143 +SM_CALL_T *ModifySecondary(RSVP_TUNNEL_PROPERTIES *pTunnel,
58144 + SM_T *pSm,
58145 + STATIC_PATH *pPrimaryStaticPath,
58146 + USER_LSP *pUserLsp);
58147 +SM_CALL_T *OptimizeSingleLsp(RSVP_TUNNEL_PROPERTIES *pTunnel,IPV4_ADDR dest,IPV4_ADDR source);
58148 +static void StopCspfRetryTimer(RSVP_TUNNEL_PROPERTIES *pTunnel);
58149 +static E_RC GetAlreadyAllocatedBW(RSVP_TUNNEL_PROPERTIES *pTunnel,void **ppLinkBw,uns32 *LinkBwNumber,float CommonBwValue);
58151 +int LspSetupTimeOut = 30;
58153 +static SM_CALL_T *lsp_sm_empty_handler(SM_T *pSm,SM_EVENT_T *sm_data)
58155 + zlog_err("lsp_sm_empty_handler, state %d",pSm->state);
58156 + return NULL;
58159 +static SM_CALL_T *lsp_sm_init(SM_T *pSm,SM_EVENT_T *sm_event)
58161 + SM_CALL_T *pCall = NULL;
58162 + RSVP_TUNNEL_PROPERTIES *pTunnel = NULL;
58163 + PSB_KEY PsbKey;
58164 + INGRESS_API *pOpenLspParams = NULL;
58165 + USER_LSP *pUserLsp,*pCurrentUserLsp;
58166 + LSP_SM_DATA *pLspSmData;
58167 + CONSTRAINT_ROUTE_RESOLUTION_ARGS *pCrArgs;
58168 + LSP_SM_NOTIF_DATA *pLspSmNotifData;
58169 + uns16 LspId = 0;
58170 + float BW = 0;
58171 + int i;
58172 + char PrimaryLspPathName[16];
58174 + pLspSmData = pSm->data;
58176 + switch(sm_event->event)
58178 + case USER_LSP_REQUEST_EVENT:
58179 + sm_gen_event_trace(sm_event->event);
58180 + pUserLsp = sm_event->data;
58181 + if((pCurrentUserLsp = UserLspGet(pUserLsp->params.LspName)) == NULL)
58183 + if(pUserLsp->params.to == 0)
58185 + zlog_err("LSP's destination cannot be 0 %s %d",__FILE__,__LINE__);
58186 + CleanSecodaryPaths(pUserLsp);
58187 + CleanUserLsp(pUserLsp);
58188 + XFREE(MTYPE_TE,pUserLsp);
58189 + return NULL;
58191 + if(pUserLsp->params.lsp_params.disable == TRUE)
58193 + zlog_err("User LSP to be deleted is not found! %s %d",__FILE__,__LINE__);
58194 + CleanSecodaryPaths(pUserLsp);
58195 + CleanUserLsp(pUserLsp);
58196 + XFREE(MTYPE_TE,pUserLsp);
58197 + return NULL;
58199 + if(UserLspAdd(pUserLsp) != E_OK)
58201 + zlog_err("cannot add user LSP %s %d",__FILE__,__LINE__);
58202 + return NULL;
58204 + pCurrentUserLsp = pUserLsp;
58206 + if(pUserLsp->params.lsp_params.disable == TRUE)
58208 + UserLspDestroy(pCurrentUserLsp);
58209 + zlog_info("Cleaning up the UserLsp memory");
58210 + if(pCurrentUserLsp != pUserLsp)
58212 + if(UserLspDelete(pCurrentUserLsp->params.LspName) != E_OK)
58214 + zlog_err(
58215 + "A problem occured while deleting an User LSP %s %d",__FILE__,__LINE__);
58218 + CleanSecodaryPaths(pUserLsp);
58219 + CleanUserLsp(pUserLsp);
58220 + XFREE(MTYPE_TE,pUserLsp);
58221 + LspSmDestroy(pSm);
58222 + return NULL;
58224 + pUserLsp->params.to = pCurrentUserLsp->params.to;
58225 + if(pUserLsp != pCurrentUserLsp)
58226 + CalculateUnneededPathAndTearDown(pUserLsp,pCurrentUserLsp);
58228 + pCall = ProcessPrimaryLsp(pCurrentUserLsp,pUserLsp,pSm,PrimaryLspPathName);
58230 + ProcessSecondaryPaths(pCurrentUserLsp,
58231 + pUserLsp,
58232 + pSm,
58233 + PrimaryLspPathName,
58234 + (pCall == NULL) ? FALSE : TRUE);
58235 + zlog_info(
58236 + "After secondary %s %s %s",
58237 + PrimaryLspPathName,pCurrentUserLsp->params.Primary,pUserLsp->params.Primary);
58238 + if(pCurrentUserLsp != pUserLsp)
58240 + if((pUserLsp->params.retry_timer != pCurrentUserLsp->params.retry_timer)||
58241 + (pUserLsp->params.retry_limit != pCurrentUserLsp->params.retry_limit))
58243 + pCurrentUserLsp->params.retry_count = pUserLsp->params.retry_limit;
58244 + if(pCurrentUserLsp->pUserLspTunnels != NULL)
58246 + StartLspSetupRetryTimer(pUserLsp->params.retry_timer,
58247 + &pCurrentUserLsp->params.retry_count,
58248 + pCurrentUserLsp->pUserLspTunnels);
58251 + CopyUserLsp(pCurrentUserLsp,pUserLsp);
58252 + XFREE(MTYPE_TE,pUserLsp);
58254 + break;
58255 + case INGRESS_LSP_REQUEST_EVENT:
58256 + sm_gen_event_trace(sm_event->event);
58257 + pOpenLspParams = sm_event->data;
58258 + pCall = LspRequest(pOpenLspParams,0,NULL,pSm,&pTunnel,FALSE,NULL);
58259 + break;
58260 + case INGRESS_LSP_DELETE_REQUEST_EVENT:
58261 + sm_gen_event_trace(sm_event->event);
58262 + memset(&PsbKey,0,sizeof(PSB_KEY));
58263 + pOpenLspParams = sm_event->data;
58264 + PsbKey.Session.Dest = pOpenLspParams->Egress;
58265 + PsbKey.Session.TunnelId = pOpenLspParams->TunnelId;
58266 + PsbKey.Session.ExtTunelId = pOpenLspParams->src_ip;
58267 + pOpenLspParams->BW = 0;
58268 + if(FindTunnel(&PsbKey,&pTunnel,ALL_TRUNKS) == TRUE)
58270 + if(RsvpTunnelTearDown(pTunnel,pOpenLspParams->Egress,pOpenLspParams->src_ip) != E_OK)
58272 + zlog_err("can not complete RSVP tunnel tear down %s %d",__FILE__,__LINE__);
58274 + XFREE(MTYPE_TE,pOpenLspParams);
58276 + else
58277 + zlog_err("Required RSVP tunnel is not found!!! %s %d",__FILE__,__LINE__);
58278 + /*LspSmDestroy(pSm);*/
58279 + break;
58280 + case LSP_SETUP_TIMER_EXPIRY:
58281 + sm_gen_event_trace(sm_event->event);
58282 + pCall = LspSetupExpiry(sm_event->data,pSm);
58283 + break;
58284 + case ADAPTIVITY_TIMER_EXPIRY:
58285 + pCall = AdaptivityExpiry(sm_event->data,pSm);
58286 + break;
58287 + case RETRY_TIMER_EXPIRY:
58288 + sm_gen_event_trace(sm_event->event);
58289 + pCall = LspSetupRetryExpiry(sm_event->data,pSm);
58290 + break;
58291 + case CSPF_RETRY_EVENT:
58292 + sm_gen_event_trace(sm_event->event);
58293 + pCall = CspfRetryExpiry(sm_event->data,pSm);
58294 + break;
58295 + case CONSTRAINT_ROUTE_RESOLVED_EVENT:
58296 + sm_gen_event_trace(sm_event->event);
58298 + pCrArgs = sm_event->data;
58300 + if(FindTunnel(&pCrArgs->PsbKey,&pTunnel,ALL_TRUNKS) != TRUE)
58302 + zlog_err("cannot find tunnel Dest %x Tunnel %x %s %d",
58303 + pCrArgs->PsbKey.Session.Dest,
58304 + pCrArgs->PsbKey.Session.TunnelId,
58305 + __FILE__,__LINE__);
58306 + XFREE(MTYPE_TE,pCrArgs);
58307 + return NULL;
58309 + if((pCrArgs->tunneled == FALSE)&&
58310 + (pCrArgs->data.path.pErHop != NULL)&&
58311 + (pCrArgs->data.path.ErHopNumber != 0))
58312 + {
58313 + int i;
58314 + zlog_info("Not tunneled, with path");
58316 + zlog_info("Insertion of returned ER hops...");
58317 + for(i = 0;i < pCrArgs->data.path.ErHopNumber;i++)
58319 + ((INGRESS_API *)(pTunnel->pOpenLspParams))->Path[i].IpAddr = pCrArgs->data.path.pErHop[i];
58320 + ((INGRESS_API *)(pTunnel->pOpenLspParams))->Path[i].PrefixLength = 32;
58322 + zlog_info("Insertion of received %d ER hops...",pCrArgs->data.path.ErHopNumber);
58323 + for(i = pCrArgs->data.path.ErHopNumber;
58324 + i < (((INGRESS_API *)(pTunnel->pOpenLspParams))->HopNum + pCrArgs->data.path.ErHopNumber);
58325 + i++)
58327 + ((INGRESS_API *)(pTunnel->pOpenLspParams))->Path[i].IpAddr
58328 + = ((INGRESS_API *)(pTunnel->pOpenLspParams))->Path[i - pCrArgs->data.path.ErHopNumber].IpAddr;
58329 + ((INGRESS_API *)(pTunnel->pOpenLspParams))->Path[i].PrefixLength = 32;
58331 + zlog_info("Done...");
58332 + ((INGRESS_API *)(pTunnel->pOpenLspParams))->HopNum += pCrArgs->data.path.ErHopNumber;
58334 + else if(pCrArgs->tunneled == TRUE)
58336 + /*pRequest->pOpenLspParams*/
58338 + zlog_info("NextHop %x %s %d",pCrArgs->OutNHop,__FILE__,__LINE__);
58339 + ((INGRESS_API *)(pTunnel->pOpenLspParams))->OutIfIndex = pCrArgs->OutIf;
58340 + ((INGRESS_API *)(pTunnel->pOpenLspParams))->NextHop = pCrArgs->OutNHop;
58341 + if(CreateAndInvokeRsvpLsp(pTunnel,
58342 + NULL,
58343 + pCrArgs->tunneled,
58344 + (pCrArgs->tunneled == TRUE) ?
58345 + &pCrArgs->data.tunnel : NULL) != E_OK)
58347 + zlog_err("cannot copy path for RSVP LSP %s %d",__FILE__,__LINE__);
58348 + LspSmDestroy(pSm);
58349 + return NULL;
58351 + if((pCrArgs->tunneled == FALSE)&&
58352 + (pCrArgs->data.path.ErHopNumber != 0))
58354 + XFREE(MTYPE_TE,pCrArgs->data.path.pErHop);
58356 + if(pCrArgs->AvoidHopNumber != 0)
58358 + XFREE(MTYPE_TE,pCrArgs->AvoidHopsArray);
58360 + if(pCrArgs->ExcludeHopNumber != 0)
58362 + XFREE(MTYPE_TE,pCrArgs->ExcludeHopsArray);
58364 + if(pCrArgs->LinkBwNumber)
58366 + XFREE(MTYPE_TE,pCrArgs->pLinkBw);
58367 + pCrArgs->pLinkBw = NULL;
58368 + pCrArgs->LinkBwNumber = 0;
58370 + XFREE(MTYPE_TE,pCrArgs);
58371 + pTunnel->pCrArgs = NULL;
58372 + StopCspfRetryTimer(pTunnel);
58373 +// return NULL;
58374 + break;
58375 + case CONSTRAINT_ROUTE_RESOLVE_FAILED_EVENT:
58376 + sm_gen_event_trace(sm_event->event);
58377 + break;
58378 + case MPLS_SIGNALING_INGRESS_ESTABLISHED_NOTIFICATION_EVENT:
58379 + sm_gen_event_trace(sm_event->event);
58381 + pLspSmNotifData = sm_event->data;
58383 + if(FindTunnel(&pLspSmNotifData->PsbKey,&pTunnel,ALL_TRUNKS) != TRUE)
58385 + zlog_err("cannot find tunnel Dest %x Tunnel %x %s %d",
58386 + pLspSmNotifData->PsbKey.Session.Dest,
58387 + pLspSmNotifData->PsbKey.Session.TunnelId,
58388 + __FILE__,__LINE__);
58389 + XFREE(MTYPE_TE,pLspSmNotifData);
58390 + return NULL;
58393 + StopLspSetupTimer(pTunnel);
58395 + if((pTunnel->properties != NULL)&&
58396 + (pTunnel->properties->next == NULL)&&
58397 + (pTunnel->properties->LspId == pTunnel->LspId))
58399 + if(pLspSmNotifData->data.setup_complete.pLspLabel)
58401 + XFREE(MTYPE_TE,pLspSmNotifData->data.setup_complete.pLspLabel);
58403 + XFREE(MTYPE_TE,pLspSmNotifData);
58404 + return NULL;
58407 + FindClosestRsvpLsp(pTunnel,&pLspSmNotifData->data.setup_complete,&BW,&LspId);
58409 + pCall = DetermineWorkingLspAndTearUnneeded(pTunnel,
58410 + BW,
58411 + LspId,
58412 + pLspSmNotifData->PsbKey.Session.Dest,
58413 + pLspSmNotifData->PsbKey.Session.ExtTunelId,
58414 + pSm);
58417 + pUserLsp = UserLspGet(pTunnel->UserLspName);
58418 + if((pUserLsp != NULL)&&(pUserLsp->pUserLspTunnels != NULL)&&
58419 + (pTunnel->TunnelId == pUserLsp->pUserLspTunnels->TunnelId))
58421 + if(strcmp(pTunnel->StaticPathName,pUserLsp->params.Primary) == 0)
58423 + if(strcmp(pUserLsp->CurrentSecondaryPathName,"") != 0)
58425 + zlog_info("Current Secondary Path Name %s Primary Path Name %s",
58426 + pUserLsp->CurrentSecondaryPathName,pUserLsp->params.Primary);
58427 + pUserLsp->CurrentSecondaryPathName[0] = '\0';
58429 + if(pUserLsp->params.retry_count != pUserLsp->params.retry_limit)
58430 + pUserLsp->params.retry_count = pUserLsp->params.retry_limit;
58431 + StopLspSetupRetryTimer(pTunnel);
58436 + if(pLspSmNotifData->data.setup_complete.pLspLabel)
58438 + XFREE(MTYPE_TE,pLspSmNotifData->data.setup_complete.pLspLabel);
58440 + XFREE(MTYPE_TE,pLspSmNotifData);
58442 + NotifySatisfiedRequests(pTunnel);
58443 + break;
58444 + case MPLS_SIGNALING_INGRESS_FAILED_NOTIFICATION_EVENT:
58445 + sm_gen_event_trace(sm_event->event);
58447 + pLspSmNotifData = sm_event->data;
58449 + if(FindTunnel(&pLspSmNotifData->PsbKey,&pTunnel,ALL_TRUNKS) != TRUE)
58451 + zlog_err("cannot find tunnel Dest %x Tunnel %x %s %d",
58452 + pLspSmNotifData->PsbKey.Session.Dest,
58453 + pLspSmNotifData->PsbKey.Session.TunnelId,
58454 + __FILE__,__LINE__);
58455 + XFREE(MTYPE_TE,pLspSmNotifData);
58456 + return NULL;
58459 + switch(pLspSmNotifData->ingress_lsp_notif)
58461 + case SETUP_FAILED_NOTIF:
58462 + RemoveRsvpLsp(pTunnel,
58463 + pLspSmNotifData->data.setup_failed.LspId,
58464 + pLspSmNotifData->PsbKey.Session.Dest,
58465 + pLspSmNotifData->PsbKey.Session.ExtTunelId);
58466 + break;
58467 + case TEAR_DOWN_NOTIF:
58468 + if(pLspSmNotifData->data.tunnel_down.NumberOfItems == 1)
58470 + RemoveRsvpLsp(pTunnel,
58471 + pLspSmNotifData->data.tunnel_down.Lsps.LspId,
58472 + pLspSmNotifData->PsbKey.Session.Dest,
58473 + pLspSmNotifData->PsbKey.Session.ExtTunelId);
58475 + else
58477 + for(i = 0;i < pLspSmNotifData->data.tunnel_down.NumberOfItems;i++)
58478 + {
58479 + RemoveRsvpLsp(pTunnel,
58480 + pLspSmNotifData->data.tunnel_down.Lsps.pLsps[i],
58481 + pLspSmNotifData->PsbKey.Session.Dest,
58482 + pLspSmNotifData->PsbKey.Session.ExtTunelId);
58485 + break;
58486 + default:
58487 + zlog_err("default case %s %d",__FILE__,__LINE__);
58489 + if(pTunnel->UserLspName[0] != '\0')
58491 + IPV4_ADDR exclude_node = 0;
58492 + if(pLspSmNotifData->ingress_lsp_notif == SETUP_FAILED_NOTIF)
58494 + exclude_node = pLspSmNotifData->data.setup_failed.IpAddr;
58495 + rdb_remote_link_router_id_get(pLspSmNotifData->data.setup_failed.IpAddr,
58496 + &exclude_node);
58498 + pCall = UserLspFailed(pTunnel,pSm,exclude_node);
58500 + else
58502 + NotifyFailedRequests(pTunnel);
58504 + XFREE(MTYPE_TE,pLspSmNotifData); /* new!!! */
58505 + break;
58506 + default:
58507 + zlog_err("unexpected event %d %s %d",
58508 + sm_event->event,
58509 + __FILE__,
58510 + __LINE__);
58511 + LspSmDestroy(pSm);
58513 + return pCall;
58516 +static SM_CALL_T* (*lsp_sm_event_handler[LSP_SM_MAX_STATE])(SM_T *pSm,SM_EVENT_T *sm_data) =
58518 + lsp_sm_empty_handler,
58519 + lsp_sm_init
58522 +SM_CALL_T *lsp_sm_handler(SM_T *pSm,SM_EVENT_T *sm_data)
58524 + if(sm_data == NULL)
58526 + zlog_err("fatal: sm_data is NULL %s %d",__FILE__,__LINE__);
58527 + LspSmDestroy(pSm);
58528 + return NULL;
58530 + if((pSm->state < INIT_STATE)||(pSm->state >= LSP_SM_MAX_STATE))
58532 + LspSmDestroy(pSm);
58533 + return NULL;
58535 + return lsp_sm_event_handler[pSm->state](pSm,sm_data);
58538 +SM_CALL_T *lsp_sm_sync_invoke(SM_T *caller,void *data,SM_EVENT_E event)
58540 + SM_T *pNewSm;
58541 + SM_CALL_T *pEvent = NULL;
58542 + LSP_SM_DATA *pLspSmData = NULL;
58543 + PSB_KEY PsbKey;
58544 + RSVP_TUNNEL_PROPERTIES *pTunnel;
58545 + INGRESS_API *pOpenLspParams;
58546 + USER_LSP *pUserLsp;
58548 + memset(&PsbKey,0,sizeof(PSB_KEY));
58550 + if(event == USER_LSP_REQUEST_EVENT)
58552 + zlog_info("%s %d",__FILE__,__LINE__);
58553 + pUserLsp = data;
58554 + PsbKey.Session.Dest = pUserLsp->params.to;
58555 + PsbKey.Session.TunnelId = GetPimaryTunnelId(pUserLsp->params.LspName);
58556 + PsbKey.Session.ExtTunelId = pUserLsp->params.from;
58557 + zlog_info("%s %d",__FILE__,__LINE__);
58559 + else
58561 + pOpenLspParams = data;
58562 + pOpenLspParams->sm_handle = (uns32)caller;
58563 + PsbKey.Session.Dest = pOpenLspParams->Egress;
58564 + PsbKey.Session.TunnelId = pOpenLspParams->TunnelId;
58565 + PsbKey.Session.ExtTunelId = pOpenLspParams->src_ip;
58568 + if(FindTunnel(&PsbKey,&pTunnel,ALL_TRUNKS) != TRUE)
58570 + zlog_info("%s %d",__FILE__,__LINE__);
58571 + pNewSm = sm_gen_alloc(0,LSP_SM);
58572 + if(pNewSm == NULL)
58574 + zlog_err("\nmalloc failed %s %d",__FILE__,__LINE__);
58575 + return NULL;
58577 + if((pLspSmData = (LSP_SM_DATA *)XMALLOC(MTYPE_TE,sizeof(LSP_SM_DATA))) == NULL)
58579 + zlog_err("\nmalloc failed %s %d",__FILE__,__LINE__);
58580 + sm_gen_free(pNewSm);
58581 + return NULL;
58583 + pNewSm->data = pLspSmData;
58585 + else if(pTunnel->sm_handle == 0)
58587 + zlog_info("%s %d",__FILE__,__LINE__);
58588 + pNewSm = sm_gen_alloc(0,LSP_SM);
58589 + if(pNewSm == NULL)
58591 + zlog_err("\nmalloc failed %s %d",__FILE__,__LINE__);
58592 + return NULL;
58595 + if((pLspSmData = (LSP_SM_DATA *)XMALLOC(MTYPE_TE,sizeof(LSP_SM_DATA))) == NULL)
58597 + zlog_err("\nmalloc failed %s %d",__FILE__,__LINE__);
58598 + sm_gen_free(pNewSm);
58599 + return NULL;
58601 + pNewSm->data = pLspSmData;
58603 + else
58605 + zlog_info("%s %d",__FILE__,__LINE__);
58606 + pNewSm = (SM_T *)pTunnel->sm_handle;
58608 + zlog_info("%s %d",__FILE__,__LINE__);
58609 + if((pEvent = sm_gen_sync_event_send(pNewSm,event,data)) == NULL)
58610 + {
58611 + zlog_err("\ncan not invoke sm %s %d",__FILE__,__LINE__);
58612 + XFREE(MTYPE_TE,pLspSmData);
58613 + sm_gen_free(pNewSm);
58615 + zlog_info("%s %d",__FILE__,__LINE__);
58616 + return pEvent;
58619 +void LspSmDestroy(SM_T *pSm)
58621 + PSB_KEY PsbKey;
58622 + RSVP_TUNNEL_PROPERTIES *pTunnel = NULL;
58623 + LSP_SM_DATA *pLspSmData = pSm->data;
58624 + TUNNEL_ID_LIST *pTunnelIdList = pLspSmData->TunnelIdHead,*pTunnelIdListNext;
58626 + while(pTunnelIdList != NULL)
58628 + memset(&PsbKey,0,sizeof(PSB_KEY));
58629 + PsbKey.Session.Dest = pTunnelIdList->dest;
58630 + PsbKey.Session.TunnelId = pTunnelIdList->tunnel_id;
58631 + PsbKey.Session.ExtTunelId = pTunnelIdList->source;
58632 + if(FindTunnel(&PsbKey,&pTunnel,ALL_TRUNKS) == TRUE)
58633 + pTunnel->sm_handle = 0;
58634 + pTunnelIdListNext = pTunnelIdList->next;
58635 + XFREE(MTYPE_TE,pTunnelIdList);
58636 + pTunnelIdList = pTunnelIdListNext;
58639 + if(pLspSmData != NULL)
58641 + XFREE(MTYPE_TE,pLspSmData);
58643 + sm_gen_free(pSm);
58646 +void UserLspDestroy(USER_LSP *pUserLsp)
58648 + RSVP_TUNNEL_PROPERTIES *pTunnel = pUserLsp->pUserLspTunnels,*pTunnelNext;
58650 + if(pTunnel == NULL)
58652 + zlog_err("\nunexpected: tunnel id list empty %s %d",__FILE__,__LINE__);
58653 + return;
58655 + while(pTunnel != NULL)
58657 + pTunnelNext = pTunnel->next_user_lsp_tunnel;
58658 + if(RsvpTunnelTearDown(pTunnel,
58659 + pUserLsp->params.to,
58660 + pUserLsp->params.from) != E_OK)
58662 + zlog_err("\ncannot tear donw the tunnel %s %d",__FILE__,__LINE__);
58664 + pTunnel = pTunnelNext;
58666 + pUserLsp->pUserLspTunnels = NULL;
58667 + return;
58671 +E_RC SetErHopList(STATIC_PATH *pStaticPath,ER_HOP **ppErHopsList)
58673 + ER_HOP *pErHopsList;
58674 + IPV4_HOP *pHops;
58675 + int i;
58676 + if(pStaticPath->HopCount == 0)
58678 + return E_OK;
58680 + if((pErHopsList = (ER_HOP *)XMALLOC(MTYPE_TE,sizeof(IPV4_HOP)*(pStaticPath->HopCount))) == NULL)
58682 + zlog_err("\nmalloc failed %s %d",__FILE__,__LINE__);
58683 + return E_ERR;
58685 + for(i = 0,pHops = pStaticPath->HopList;i < pStaticPath->HopCount;i++,pHops = pHops->next)
58687 + pErHopsList[i].IpAddr = pHops->IpAddr;
58688 + pErHopsList[i].Loose = pHops->Loose;
58689 + pErHopsList[i].PrefixLength = 32;
58691 + *ppErHopsList = pErHopsList;
58692 + return E_OK;
58695 +SM_CALL_T *ProcessPrimaryLsp(USER_LSP *pCurrentUserLsp,
58696 + USER_LSP *pUserLsp,
58697 + SM_T *pSm,
58698 + char *PrimaryLspPathName)
58700 + SM_CALL_T *pCall = NULL;
58701 + INGRESS_API *pOpenLspParams = NULL;
58702 + PSB_KEY PsbKey;
58703 + RSVP_TUNNEL_PROPERTIES *pPrimaryTunnel;
58704 + STATIC_PATH *pStaticPath = NULL;
58705 + SECONDARY_PATH_LIST *pSecList;
58706 + LSP_PATH_SHARED_PARAMS *pParams = NULL,*pParams2;
58707 + BOOL OperationRequired = FALSE;
58708 + uns8 Flags = 0;
58709 + ER_HOP *pErHopsList = NULL;
58710 + zlog_info("entering ProcessPrimaryLsp");
58711 + zlog_info("LSP NAME %s",pCurrentUserLsp->params.LspName);
58713 + if((pPrimaryTunnel = pCurrentUserLsp->pUserLspTunnels) == NULL)
58715 + memset(&PsbKey,0,sizeof(PSB_KEY));
58716 + PsbKey.Session.Dest = pUserLsp->params.to;
58717 + PsbKey.Session.TunnelId = NewTunnelId(&PsbKey);
58718 + PsbKey.Session.ExtTunelId = pUserLsp->params.from = rdb_get_router_id();
58719 + if(NewTunnel(&PsbKey,&pPrimaryTunnel,SEPARATE_NON_ADAPTIVE) != E_OK)
58721 + zlog_err("Cannot create new tunnel %s %d",__FILE__,__LINE__);
58722 + return NULL;
58724 + pCurrentUserLsp->pUserLspTunnels = pPrimaryTunnel;
58725 + zlog_info("New tunnel (Primary) created %x %s",pPrimaryTunnel->TunnelId,pPrimaryTunnel->StaticPathName);
58726 + OperationRequired = TRUE;
58728 + strcpy(PrimaryLspPathName,pUserLsp->params.Primary);
58729 + strcpy(pPrimaryTunnel->StaticPathName,PrimaryLspPathName);
58730 + /* calculate the primary LSP parameters */
58731 + if((!((pUserLsp->params.PrimaryPathParams)&&(!pUserLsp->params.PrimaryPathParams->disable)))||
58732 + (rdb_get_static_path(pUserLsp->params.Primary,&pStaticPath) != E_OK))
58734 + zlog_info("No primary path...");
58735 + pSecList = pUserLsp->params.SecondaryPaths;
58736 + while(pSecList != NULL)
58738 + if(((pSecList->SecondaryPathParams)&&(pSecList->SecondaryPathParams->standby == 0))&&
58739 + (rdb_get_static_path(pSecList->Secondary,&pStaticPath) == E_OK))
58741 + zlog_info("Processing secondary path %s",pSecList->Secondary);
58742 + if(StaticPathIsUsed(pCurrentUserLsp,pSecList->Secondary) == NULL)
58744 + zlog_info("\nSecondary path hasn't LSP");
58745 + pParams = PathParamsGet(pUserLsp,pSecList->Secondary,0);
58746 + Flags |= (pParams->record == TRUE) ? LABEL_RECORDING_DESIRED : 0;
58747 + /* for now the FRR is only boolean. However, in future it may be more complicated */
58748 + Flags |= (pUserLsp->params.FastReRoute == TRUE) ? LOCAL_PROTECTION_DESIRED : 0;
58749 + if(SetErHopList(pStaticPath,&pErHopsList) != E_OK)
58751 + zlog_err("Cannot set ER hops list %s %d",__FILE__,__LINE__);
58752 + return NULL;
58754 + if((pOpenLspParams = CreateRequest2Signalling(pCurrentUserLsp->params.to,
58755 + pPrimaryTunnel->TunnelId,
58756 + pStaticPath->HopCount,
58757 + pErHopsList,
58758 + pParams->BW,
58759 + pParams->setup_priority,
58760 + pParams->hold_priority,
58761 + Flags,
58762 + (~(pParams->affinity_properties & pParams->affinity_mask)) & pParams->affinity_mask,
58763 + 0,
58764 + pParams->affinity_properties & pParams->affinity_mask)) == NULL)
58766 + zlog_err("\nmalloc failed %s %d",__FILE__,__LINE__);
58767 + if(pErHopsList != NULL)
58768 + XFREE(MTYPE_TE,pErHopsList);
58769 + return NULL;
58771 + strcpy(PrimaryLspPathName,pSecList->Secondary);
58772 + OperationRequired = TRUE;
58773 + break;
58775 + pStaticPath = NULL;
58777 + pSecList = pSecList->next;
58779 + if((pUserLsp->params.PrimaryPathParams != NULL)&&
58780 + (!pUserLsp->params.PrimaryPathParams->disable))
58782 + pParams = pUserLsp->params.PrimaryPathParams;
58784 + else
58786 + pParams = &pUserLsp->params.lsp_params;
58788 + if(pCurrentUserLsp->params.PrimaryPathParams != NULL)
58790 + pParams2 = pCurrentUserLsp->params.PrimaryPathParams;
58792 + else
58794 + pParams2 = &pCurrentUserLsp->params.lsp_params;
58796 + if((pStaticPath == NULL)&&
58797 + ((pParams->BW != pParams2->BW)||
58798 + (pParams->class_of_service != pParams2->class_of_service)||
58799 + (pParams->hold_priority != pParams2->hold_priority)||
58800 + (pParams->setup_priority != pParams2->setup_priority)||
58801 + (pParams->hop_limit != pParams2->hop_limit)||
58802 + (pParams->record != pParams2->record)||
58803 + (pUserLsp->params.FastReRoute != pCurrentUserLsp->params.FastReRoute)||
58804 + (pUserLsp == pCurrentUserLsp)))
58806 + zlog_info("no paths provided");
58807 + Flags |= (pUserLsp->params.lsp_params.record == TRUE) ? LABEL_RECORDING_DESIRED : 0;
58808 + /* for now the FRR is only boolean. However, in future it may be more complicated */
58809 + Flags |= (pUserLsp->params.FastReRoute == TRUE) ? LOCAL_PROTECTION_DESIRED : 0;
58810 + if((pOpenLspParams = CreateRequest2Signalling(pCurrentUserLsp->params.to,
58811 + pPrimaryTunnel->TunnelId,
58812 + 0,NULL,
58813 + pParams->BW,
58814 + pParams->setup_priority,
58815 + pParams->hold_priority,
58816 + Flags,
58817 + (~(pParams->affinity_properties & pParams->affinity_mask)) & pParams->affinity_mask,
58818 + 0,
58819 + pParams->affinity_properties & pParams->affinity_mask)) == NULL)
58821 + zlog_err("\ncannot create request %s %d",__FILE__,__LINE__);
58822 + return NULL;
58824 + OperationRequired = TRUE;
58826 + else if(pStaticPath == NULL)
58828 + if(pParams->optimize_timer != pParams2->optimize_timer)
58830 + StartAdaptivityTimer(pParams->optimize_timer,pPrimaryTunnel);
58834 + else
58836 + zlog_info(
58837 + "\nCurrent Primary %s New Primary %s",
58838 + pCurrentUserLsp->params.Primary,pUserLsp->params.Primary);
58839 + if((pUserLsp->params.PrimaryPathParams != NULL)&&
58840 + (!pUserLsp->params.PrimaryPathParams->disable))
58842 + pParams = pUserLsp->params.PrimaryPathParams;
58844 + else
58846 + pParams = &pUserLsp->params.lsp_params;
58848 + if(pCurrentUserLsp->params.PrimaryPathParams != NULL)
58850 + pParams2 = pCurrentUserLsp->params.PrimaryPathParams;
58852 + else
58854 + pParams2 = &pCurrentUserLsp->params.lsp_params;
58856 + if((pParams->BW != pParams2->BW)||
58857 + (pParams->class_of_service != pParams2->class_of_service)||
58858 + (pParams->hold_priority != pParams2->hold_priority)||
58859 + (pParams->setup_priority != pParams2->setup_priority)||
58860 + (pParams->hop_limit != pParams2->hop_limit)||
58861 + (pParams->record != pParams2->record)||
58862 + (pUserLsp->params.FastReRoute != pCurrentUserLsp->params.FastReRoute))
58864 + OperationRequired = TRUE;
58867 + if(strcmp(pCurrentUserLsp->params.Primary,pUserLsp->params.Primary) != 0)
58869 + OperationRequired = TRUE;
58872 + if(pCurrentUserLsp->params.FastReRoute != pUserLsp->params.FastReRoute)
58874 + OperationRequired = TRUE;
58877 + if(OperationRequired == TRUE)
58879 + zlog_info("Parameters have changed");
58880 + pParams = PathParamsGet(pUserLsp,pUserLsp->params.Primary,1);
58881 + Flags |= (pParams->record == TRUE) ? LABEL_RECORDING_DESIRED : 0;
58882 + /* for now the FRR is only boolean. However, in future it may be more complicated */
58883 + Flags |= (pUserLsp->params.FastReRoute == TRUE) ? LOCAL_PROTECTION_DESIRED : 0;
58884 + if(SetErHopList(pStaticPath,&pErHopsList) != E_OK)
58886 + zlog_err("Cannot set ER hops list %s %d",__FILE__,__LINE__);
58887 + return NULL;
58889 + if((pOpenLspParams = CreateRequest2Signalling(pCurrentUserLsp->params.to,
58890 + pPrimaryTunnel->TunnelId,
58891 + pStaticPath->HopCount,
58892 + pErHopsList,
58893 + pParams->BW,
58894 + pParams->setup_priority,
58895 + pParams->hold_priority,
58896 + Flags,
58897 + (~(pParams->affinity_properties & pParams->affinity_mask)) & pParams->affinity_mask,
58898 + 0,
58899 + pParams->affinity_properties & pParams->affinity_mask)) == NULL)
58901 + zlog_err("\nmalloc failed %s %d",__FILE__,__LINE__);
58902 + if(pErHopsList != NULL)
58903 + XFREE(MTYPE_TE,pErHopsList);
58904 + return NULL;
58907 + else
58909 + if(pParams->optimize_timer != pParams2->optimize_timer)
58911 + StartAdaptivityTimer(pParams->optimize_timer,pPrimaryTunnel);
58915 + if(OperationRequired == TRUE)
58917 + /* setup the primary LSP */
58918 + pOpenLspParams->TunnelId = pPrimaryTunnel->TunnelId;
58919 + zlog_info(
58920 + "\nDEST %x SOURCE %x TUNNEL %x",
58921 + pOpenLspParams->Egress,pOpenLspParams->src_ip,pOpenLspParams->TunnelId);
58922 + pCall = LspRequest(pOpenLspParams,0,NULL,pSm,&pPrimaryTunnel,FALSE,pParams);
58923 + pPrimaryTunnel->sm_handle = pSm;
58924 + strcpy(pPrimaryTunnel->StaticPathName,PrimaryLspPathName);
58925 + strcpy(pPrimaryTunnel->UserLspName,pUserLsp->params.LspName);
58926 + zlog_info("\nPrimary Tunnel Name %s",pPrimaryTunnel->UserLspName);
58928 + zlog_info("leaving ProcessPrimaryLsp");
58929 + return pCall;
58932 +RSVP_TUNNEL_PROPERTIES *GetSecondaryTunnel2Reroute(USER_LSP *pUserLsp,
58933 + USER_LSP *pCurrentUserLsp)
58935 + RSVP_TUNNEL_PROPERTIES *pTunnel;
58936 + SECONDARY_PATH_LIST *pSecList;
58937 + BOOL Found;
58938 + zlog_info("entering GetSecondaryTunnel2Reroute");
58939 + if((pTunnel = pCurrentUserLsp->pUserLspTunnels) == NULL)
58941 + zlog_err(
58942 + "\nBUG: first Tunnel ID is NULL %s %d %s",
58943 + __FILE__,__LINE__,pCurrentUserLsp->params.LspName);
58944 + return NULL;
58946 + pTunnel = pTunnel->next_user_lsp_tunnel;
58947 + while(pTunnel != NULL)
58949 + pSecList = pUserLsp->params.SecondaryPaths;
58950 + Found = FALSE;
58951 + while(pSecList != NULL)
58953 + if((pSecList->SecondaryPathParams != NULL)&&
58954 + (pSecList->SecondaryPathParams->standby == TRUE))
58956 + if(strcmp(pSecList->Secondary,pTunnel->StaticPathName) == 0)
58958 + Found = TRUE;
58959 + break;
58962 + pSecList = pSecList->next;
58964 + if(Found == FALSE)
58966 + /* should we do some clean up like stop the timers etc ??? */
58967 + return pTunnel;
58969 + pTunnel = pTunnel->next_user_lsp_tunnel;
58971 + zlog_info("leaving GetSecondaryTunnel2Reroute");
58972 + return NULL;
58975 +SM_CALL_T *ProcessSecondaryPaths(USER_LSP *pCurrentUserLsp,
58976 + USER_LSP *pUserLsp,
58977 + SM_T *pSm,
58978 + char *PrimaryLspPathName,
58979 + BOOL PrimaryLspOperation)
58981 + SECONDARY_PATH_LIST *pSecList;
58982 + BOOL OperationRequired;
58983 + INGRESS_API *pOpenLspParams;
58984 + RSVP_TUNNEL_PROPERTIES *pSecondaryTunnel,*pSecTunnel2Modify,*pSecReusedTunnel;
58985 + STATIC_PATH *pStaticPath;
58986 + PSB_KEY PsbKey;
58987 + LSP_PATH_SHARED_PARAMS *pParams = NULL,*pParams2;
58988 + uns8 Flags = 0;
58989 + ER_HOP *pErHopsList = NULL;
58990 + SM_CALL_T *pCall = NULL;
58992 + zlog_info("entering ProcessSecondaryPaths");
58994 + pSecList = pUserLsp->params.SecondaryPaths;
58996 + /* find all the secondary LSPs (hot-standby) that must be established */
58997 + while(pSecList != NULL)
58999 + OperationRequired = FALSE;
59000 + pCall = NULL;
59001 + pErHopsList = NULL;
59002 + zlog_info("Secondary path...");
59003 + if((pSecList->SecondaryPathParams != NULL)&&
59004 + (pSecList->SecondaryPathParams->disable == FALSE)&&
59005 + (pSecList->SecondaryPathParams->standby == TRUE))
59007 + zlog_info("Secondary path2...");
59008 + if(rdb_get_static_path(pSecList->Secondary,
59009 + &pStaticPath) != E_OK)
59011 + zlog_info("static path is not found in TE DB");
59012 + pStaticPath = NULL;
59014 + else
59016 + if(SetErHopList(pStaticPath,&pErHopsList) != E_OK)
59018 + zlog_err("Cannot set ER hops list %s %d",__FILE__,__LINE__);
59019 + return NULL;
59022 + pSecReusedTunnel = NULL;
59023 + pParams = PathParamsGet(pUserLsp,pSecList->Secondary,0);
59024 + if((pSecTunnel2Modify = StaticPathIsUsed(pCurrentUserLsp,pSecList->Secondary)) == NULL)
59026 + zlog_info("Secondary path3 ...");
59028 + if((pSecReusedTunnel = GetSecondaryTunnel2Reroute(pUserLsp,pCurrentUserLsp)) != NULL)
59030 + strcpy(pSecReusedTunnel->StaticPathName,pSecList->Secondary);
59032 + OperationRequired = TRUE;
59034 + else
59036 + pParams2 = PathParamsGet(pCurrentUserLsp,pSecList->Secondary,0);
59037 + pSecReusedTunnel = pSecTunnel2Modify;
59038 + if((pParams->BW != pParams2->BW)||
59039 + (pParams->class_of_service != pParams2->class_of_service)||
59040 + (pParams->hold_priority != pParams2->hold_priority)||
59041 + (pParams->setup_priority != pParams2->setup_priority)||
59042 + (pParams->hop_limit != pParams2->hop_limit)||
59043 + (pParams->record != pParams2->record)||
59044 + (pUserLsp->params.FastReRoute != pCurrentUserLsp->params.FastReRoute))
59046 + OperationRequired = TRUE;
59048 + if(pCurrentUserLsp->params.FastReRoute != pUserLsp->params.FastReRoute)
59050 + OperationRequired = TRUE;
59052 + if(OperationRequired == FALSE)
59054 + if(pParams->optimize_timer != pParams2->optimize_timer)
59056 + StartAdaptivityTimer(pParams->optimize_timer,pSecReusedTunnel);
59060 + if(OperationRequired == TRUE)
59062 + if((((pStaticPath != NULL)&&(pStaticPath->HopCount != 0))&&
59063 + ((pErHopsList != NULL)&&(pErHopsList[0].Loose == 0)))||
59064 + (PrimaryLspOperation == FALSE))
59066 + uns32 ErHopNumber = 0;
59067 + IPV4_ADDR *pErHops = NULL;
59068 + if(!((pErHopsList != NULL)&&(pErHopsList[0].Loose == 0)))
59070 + if(GetTunnelHops(pCurrentUserLsp->pUserLspTunnels,
59071 + &ErHopNumber,
59072 + &pErHops) != E_OK)
59074 + zlog_info(
59075 + "cannot get ER HOPs to be avoided %s %d",
59076 + __FILE__,__LINE__);
59077 + ErHopNumber = 0;
59078 + pErHops = NULL;
59081 + memset(&PsbKey,0,sizeof(PSB_KEY));
59082 + PsbKey.Session.Dest = pUserLsp->params.to;
59083 + Flags |= pParams->record == TRUE ? LABEL_RECORDING_DESIRED : 0;
59084 + /* for now the FRR is only boolean. However, in future it may be more complicated */
59085 + Flags |= (pUserLsp->params.FastReRoute == TRUE) ? LOCAL_PROTECTION_DESIRED : 0;
59086 + if((pOpenLspParams = CreateRequest2Signalling(pUserLsp->params.to,
59087 + (pSecReusedTunnel == NULL) ?
59088 + NewTunnelId(&PsbKey) : pSecReusedTunnel->TunnelId,
59089 + (pStaticPath == NULL) ? 0 : pStaticPath->HopCount,
59090 + pErHopsList,
59091 + pParams->BW,
59092 + pParams->setup_priority,
59093 + pParams->hold_priority,
59094 + Flags,
59095 + (~(pParams->affinity_properties & pParams->affinity_mask)) & pParams->affinity_mask,
59096 + 0,
59097 + pParams->affinity_properties & pParams->affinity_mask)) == NULL)
59099 + zlog_err("\nmalloc failed %s %d",__FILE__,__LINE__);
59100 + return NULL;
59102 + pCall = LspRequest(pOpenLspParams,
59103 + ErHopNumber,
59104 + pErHops,
59105 + pSm,
59106 + &pSecondaryTunnel,
59107 + TRUE,
59108 + pParams);
59109 + pSecondaryTunnel->sm_handle = pSm;
59110 + if(AddSecondaryTunnel(pCurrentUserLsp,
59111 + pSecondaryTunnel) != E_OK)
59113 + zlog_err("\ncannot add secodary tunnel to the list %s %d",
59114 + __FILE__,__LINE__);
59115 + return NULL;
59118 + else
59120 + uns16 TunnelId;
59121 + if(pSecReusedTunnel == NULL)
59123 + memset(&PsbKey,0,sizeof(PsbKey));
59124 + PsbKey.Session.Dest = pUserLsp->params.to;
59125 + PsbKey.Session.ExtTunelId = pUserLsp->params.from;
59126 + TunnelId = NewTunnelId(&PsbKey);
59127 + PsbKey.Session.TunnelId = TunnelId;
59128 + zlog_info("DEST %x TUNNEL %x SOURCE %x",
59129 + PsbKey.Session.Dest,
59130 + PsbKey.Session.TunnelId,
59131 + PsbKey.Session.ExtTunelId);
59132 + if(NewTunnel(&PsbKey,&pSecondaryTunnel,SEPARATE_NON_ADAPTIVE) != E_OK)
59134 + zlog_err("\ncannot create new tunnel's structure");
59135 + LspSmDestroy(pSm);
59136 + return NULL;
59139 + else
59141 + pSecondaryTunnel = pSecReusedTunnel;
59144 + pSecondaryTunnel->RequiredBW = pParams->BW;
59145 + pSecondaryTunnel->sm_handle = pSm;
59146 + if(AddSecondaryTunnel(pCurrentUserLsp,
59147 + pSecondaryTunnel) != E_OK)
59149 + zlog_err("\ncannot add secodary tunnel to the list %s %d",
59150 + __FILE__,__LINE__);
59151 + return NULL;
59153 + pSecondaryTunnel->AdjustmentRequired = TRUE;
59155 + zlog_info("after UserLSpRequest %s %d %x",__FILE__,__LINE__,pSecondaryTunnel->TunnelId);
59156 + if(pSecondaryTunnel != NULL)
59158 + strcpy(pSecondaryTunnel->StaticPathName,pSecList->Secondary);
59159 + strcpy(pSecondaryTunnel->UserLspName,pUserLsp->params.LspName);
59160 + zlog_info("pSecondaryTunnel->StaticPathName %s pSecondaryTunnel->UserLspName %s",
59161 + pSecondaryTunnel->StaticPathName,pSecondaryTunnel->UserLspName);
59163 + if(pCall)
59165 + sm_call(pCall);
59166 + pCall = NULL;
59170 + pSecList = pSecList->next;
59172 + zlog_info("leaving ProcessSecondaryPaths");
59173 + return NULL;
59176 +uns32 StartAdaptivityTimer(uns32 optimize_timer,
59177 + RSVP_TUNNEL_PROPERTIES *pTunnel)
59179 + zlog_info("entering StartAdaptivityTimer");
59181 + if(pTunnel->adaptivity_timer.is_active == TRUE)
59183 + te_stop_timer(&pTunnel->adaptivity_timer);
59185 + zlog_info("triggering optimize timer for tunnel %x value %d",pTunnel->TunnelId,optimize_timer);
59186 + if(optimize_timer != 0)
59188 + if(te_start_timer(&pTunnel->adaptivity_timer,
59189 + ADAPTIVITY_EXPIRY,
59190 + optimize_timer) != E_OK)
59192 + zlog_err("\ncannot start adaptivity timer %s %d",__FILE__,__LINE__);
59193 + return E_ERR;
59196 + else
59198 + zlog_info("\nOptimize timer is 0...");
59200 + zlog_info("leaving StartAdaptivityTimer");
59201 + return E_OK;
59204 +void StopAdaptivityTimer(RSVP_TUNNEL_PROPERTIES *pTunnel)
59206 + zlog_info("entering StopAdaptivityTimer");
59207 + te_stop_timer(&pTunnel->adaptivity_timer);
59208 + zlog_info("leaving StopAdaptivityTimer");
59211 +uns32 StartLspSetupTimer(RSVP_TUNNEL_PROPERTIES *pTunnel)
59213 + zlog_info("entering StartLspSetupTimer");
59214 + //return E_OK;
59215 + if(pTunnel->lsp_setup_timer.is_active == TRUE)
59217 + te_stop_timer(&pTunnel->lsp_setup_timer);
59219 + if(te_start_timer(&pTunnel->lsp_setup_timer,
59220 + LSP_SETUP_EXPIRY,
59221 + LspSetupTimeOut) != E_OK)
59223 + zlog_err("\ncannot start te timer %s %d",__FILE__,__LINE__);
59224 + return E_ERR;
59226 + zlog_info("leaving StartLspSetupTimer");
59227 + return E_OK;
59230 +void StopLspSetupTimer(RSVP_TUNNEL_PROPERTIES *pTunnel)
59232 + zlog_info("entering StopLspSetupTimer");
59233 + te_stop_timer(&pTunnel->lsp_setup_timer);
59234 + zlog_info("leaving StopLspSetupTimer");
59237 +uns32 StartLspSetupRetryTimer(uns32 retry_timer,
59238 + uns32 *retry_count,
59239 + RSVP_TUNNEL_PROPERTIES *pTunnel)
59241 + zlog_info("entering StartLspSetupRetryTimer");
59243 + if(*retry_count > 0)
59245 + if(retry_timer != 0)
59247 + if(pTunnel->lsp_setup_retry_timer.is_active == TRUE)
59249 + te_stop_timer(&pTunnel->lsp_setup_retry_timer);
59251 + zlog_info("\ninside of StartLspSetupRetryTimer %x %x %x",
59252 + pTunnel->lsp_setup_retry_timer.data.lsp_setup_retry_data.key.Session.Dest,
59253 + pTunnel->lsp_setup_retry_timer.data.lsp_setup_retry_data.key.Session.TunnelId,
59254 + pTunnel->lsp_setup_retry_timer.data.lsp_setup_retry_data.key.Session.ExtTunelId);
59255 + if(te_start_timer(&pTunnel->lsp_setup_retry_timer,
59256 + LSP_SETUP_RETRY_EXPIRY,
59257 + retry_timer) != E_OK)
59259 + zlog_err("\ncannot start te timer %s %d",__FILE__,__LINE__);
59260 + return E_ERR;
59263 + (*retry_count)--;
59265 + zlog_info("leaving StartLspSetupRetryTimer");
59266 + return E_OK;
59269 +void StopLspSetupRetryTimer(RSVP_TUNNEL_PROPERTIES *pTunnel)
59271 + zlog_info("entering StopLspSetupTimer");
59272 + te_stop_timer(&pTunnel->lsp_setup_retry_timer);
59273 + zlog_info("leaving StopLspSetupRetryTimer");
59276 +uns32 StartCspfRetryTimer(RSVP_TUNNEL_PROPERTIES *pTunnel)
59278 + int r,k;
59279 + zlog_info("entering StartCspfRetryTimer");
59281 + if(pTunnel->cspf_retry_timer.is_active == TRUE)
59283 + te_stop_timer(&pTunnel->cspf_retry_timer);
59285 + zlog_info("inside of StartCspfRetryTimer %x %x %x",
59286 + pTunnel->cspf_retry_timer.data.cspf_retry_data.key.Session.Dest,
59287 + pTunnel->cspf_retry_timer.data.cspf_retry_data.key.Session.TunnelId,
59288 + pTunnel->cspf_retry_timer.data.cspf_retry_data.key.Session.ExtTunelId);
59289 + r = rand();
59290 + r = r%30;
59291 + k = rand();
59292 + if(te_start_timer(&pTunnel->cspf_retry_timer,
59293 + CSPF_RETRY_EXPIRY,
59294 + /*(k%2) ? (300 + r) : (300 - r)*/5) != E_OK)
59296 + zlog_err("\ncannot start te timer %s %d",__FILE__,__LINE__);
59297 + return E_ERR;
59299 + zlog_info("leaving StartCspfRetryTimer");
59300 + return E_OK;
59303 +static void StopCspfRetryTimer(RSVP_TUNNEL_PROPERTIES *pTunnel)
59305 + zlog_info("entering StopCspfRetryTimer");
59306 + te_stop_timer(&pTunnel->cspf_retry_timer);
59307 + zlog_info("leaving StopCspfRetryTimer");
59310 +SM_CALL_T *CspfRetryExpiry(PSB_KEY *PsbKey,SM_T *pSm)
59312 + RSVP_TUNNEL_PROPERTIES *pTunnel;
59313 + SM_CALL_T *pCall = NULL;
59315 + zlog_info("entering CspfRetryExpiry");
59317 + if(FindTunnel(PsbKey,&pTunnel,ALL_TRUNKS) != TRUE)
59319 + zlog_info("leaving CspfRetryExpiry1-");
59320 + return NULL;
59323 + if((pTunnel->pOpenLspParams)&&(pTunnel->pCrArgs))
59325 + ((INGRESS_API *)(pTunnel->pOpenLspParams))->ErHops2Exclude[0] = 0;
59326 + ((INGRESS_API *)(pTunnel->pOpenLspParams))->ErHops2Exclude[1] = 0;
59327 + UnregisterClient((int)pSm,
59328 + pTunnel->TunnelId);
59329 + if((pCall = constraint_route_resolution_sm_invoke(pSm,
59330 + pTunnel->pCrArgs)) == NULL)
59332 + zlog_err("cannot invoke constraint route resolution");
59333 + return NULL;
59336 + StartCspfRetryTimer(pTunnel);
59337 + zlog_info("leaving CspfRetryExpiry");
59338 + return pCall;
59341 +SM_CALL_T *LspSetupExpiry(PSB_KEY *PsbKey,SM_T *pSm)
59343 + RSVP_TUNNEL_PROPERTIES *pTunnel;
59344 + RSVP_LSP_PROPERTIES *pRsvpLsp;
59346 + zlog_info("entering LspSetupExpiry");
59348 + if(FindTunnel(PsbKey,&pTunnel,ALL_TRUNKS) != TRUE)
59350 + zlog_err("\ncannot find tunnel %x %x %x %s %d",
59351 + PsbKey->Session.Dest,
59352 + PsbKey->Session.TunnelId,
59353 + PsbKey->Session.ExtTunelId,__FILE__,__LINE__);
59354 + return NULL;
59356 + pRsvpLsp = pTunnel->properties;
59357 + while(pRsvpLsp != NULL)
59359 + if(pRsvpLsp->LspId != pTunnel->LspId)
59361 + RSVP_LSP_PROPERTIES *pTemp = pRsvpLsp->next;
59362 + RemoveRsvpLsp(pTunnel,pRsvpLsp->LspId,PsbKey->Session.Dest,PsbKey->Session.ExtTunelId);
59363 + pRsvpLsp = pTemp;
59365 + else
59367 + pRsvpLsp = pRsvpLsp->next;
59370 + //pTunnel->ReRoute = FALSE;
59371 + if(pTunnel->UserLspName[0] != '\0')
59373 + return UserLspFailed(pTunnel,pSm,0);
59375 + else
59377 + NotifyFailedRequests(pTunnel);
59379 + zlog_info("leaving LspSetupExpiry");
59380 + return NULL;
59383 +SM_CALL_T *AdaptivityExpiry(PSB_KEY *PsbKey,SM_T *pSm)
59385 + RSVP_TUNNEL_PROPERTIES *pTunnel;
59386 + USER_LSP *pUserLsp;
59387 + STATIC_PATH *pStaticPath;
59389 + zlog_info("entering AdaptivityExpiry");
59391 + if(FindTunnel(PsbKey,&pTunnel,ALL_TRUNKS) != TRUE)
59393 + zlog_err("\ncannot find tunnel %x %x %x %s %d",
59394 + PsbKey->Session.Dest,
59395 + PsbKey->Session.TunnelId,
59396 + PsbKey->Session.ExtTunelId,
59397 + __FILE__,__LINE__);
59398 + return NULL;
59401 + if((pUserLsp = UserLspGet(pTunnel->UserLspName)) != 0)
59403 + LSP_PATH_SHARED_PARAMS *pParams = PathParamsGet(pUserLsp,
59404 + pTunnel->StaticPathName,
59405 + ((!strcmp(pUserLsp->params.Primary,pTunnel->StaticPathName))&&(pUserLsp->pUserLspTunnels->TunnelId == pTunnel->TunnelId)));
59407 + if(pParams == NULL)
59409 + zlog_err("\ncannot get User Lsp PAth Params %s %d",__FILE__,__LINE__);
59411 + else
59413 + if(StartAdaptivityTimer(pParams->optimize_timer,pTunnel) != E_OK)
59415 + zlog_err("\ncannot start adaptivity timer %s %d",__FILE__,__LINE__);
59419 + if(pTunnel->ReRoute == FALSE)
59421 + IPV4_ADDR dest = PsbKey->Session.Dest;
59423 + if(rdb_get_static_path(pTunnel->StaticPathName,
59424 + &pStaticPath) == E_OK)
59426 + if(pStaticPath->HopCount != 0)
59428 + if(pStaticPath->HopList->Loose == 0)
59430 + return NULL;
59432 + else
59434 + dest = pStaticPath->HopList->IpAddr;
59438 + return OptimizeSingleLsp(pTunnel,
59439 + dest,
59440 + PsbKey->Session.ExtTunelId);
59442 + else
59444 + zlog_info("\nDEBUG: No adaptation during reroute %x %x %x %s %d",
59445 + PsbKey->Session.Dest,
59446 + PsbKey->Session.TunnelId,
59447 + PsbKey->Session.ExtTunelId,
59448 + __FILE__,__LINE__);
59451 + zlog_info("leaving AdaptivityExpiry");
59452 + return NULL;
59455 +SM_CALL_T *LspSetupRetryExpiry(PSB_KEY *PsbKey,SM_T *pSm)
59457 + RSVP_TUNNEL_PROPERTIES *pTunnel;
59458 + USER_LSP *pUserLsp;
59459 + STATIC_PATH *pStaticPath;
59460 + INGRESS_API *pOpenLspParams;
59461 + SM_CALL_T *pCall = NULL;
59462 + uns32 ErHops2BeAvoidedNumber = 0;
59463 + IPV4_ADDR *ErHops2BeAvoided = NULL;
59464 + LSP_PATH_SHARED_PARAMS *pParams;
59465 + ER_HOP *pErHopsList = NULL;
59466 + uns8 Flags = 0;
59468 + zlog_info("entering LspSetupRetryExpiry");
59470 + if(FindTunnel(PsbKey,&pTunnel,ALL_TRUNKS) != TRUE)
59472 + zlog_err("\ncannot find tunnel %x %x %x %s %d",
59473 + PsbKey->Session.Dest,
59474 + PsbKey->Session.TunnelId,
59475 + PsbKey->Session.ExtTunelId,
59476 + __FILE__,__LINE__);
59477 + return NULL;
59479 + if((pUserLsp = UserLspGet(pTunnel->UserLspName)) == NULL)
59481 + zlog_err("\ncannot get user lsp %s %d",__FILE__,__LINE__);
59482 + return NULL;
59484 + if(rdb_get_static_path(pUserLsp->params.Primary,
59485 + &pStaticPath) != E_OK)
59487 + pStaticPath = NULL;
59489 + pParams = PathParamsGet(pUserLsp,pUserLsp->params.Primary,1);
59490 + Flags |= (pParams->record == TRUE) ? LABEL_RECORDING_DESIRED : 0;
59491 + /* for now the FRR is only boolean. However, in future it may be more complicated */
59492 + Flags |= (pUserLsp->params.FastReRoute == TRUE) ? LOCAL_PROTECTION_DESIRED : 0;
59493 + if(pStaticPath)
59495 + if(SetErHopList(pStaticPath,&pErHopsList) != E_OK)
59497 + zlog_err("Cannot set ER hops list %s %d",__FILE__,__LINE__);
59498 + return NULL;
59501 + if((pOpenLspParams = CreateRequest2Signalling(pUserLsp->params.to,
59502 + pUserLsp->pUserLspTunnels->TunnelId,
59503 + (pStaticPath) ? pStaticPath->HopCount : 0,
59504 + pErHopsList,
59505 + pParams->BW,
59506 + pParams->setup_priority,
59507 + pParams->hold_priority,
59508 + Flags,
59509 + (~(pParams->affinity_properties & pParams->affinity_mask)) & pParams->affinity_mask,
59510 + 0,
59511 + pParams->affinity_properties & pParams->affinity_mask)) == NULL)
59513 + zlog_err("\nmalloc failed %s %d",__FILE__,__LINE__);
59514 + XFREE(MTYPE_TE,pErHopsList);
59515 + return NULL;
59518 +#if 0
59519 + if((pTunnelIdList = pUserLsp->TunnelIdList) == NULL)
59521 + zlog_info("\nUser's LSP tunnel ID list is empty...");
59523 + else
59525 + RSVP_TUNNEL_PROPERTIES *pTun;
59526 + PSB_KEY rsvp_k;
59527 + memset(&rsvp_k,0,sizeof(PSB_KEY));
59528 + rsvp_k.Session.Dest = pTunnelIdList->dest;
59529 + rsvp_k.Session.ExtTunelId = pTunnelIdList->source;
59530 + pTunnelIdList = pTunnelIdList->next;
59531 + while(pTunnelIdList != NULL)
59533 + rsvp_k.Session.TunnelId = pTunnelIdList->tunnel_id;
59534 + if(FindTunnel(&rsvp_k,&pTun,ALL_TRUNKS) == TRUE)
59536 + if(strcmp(pUserLsp->CurrentSecondaryPathName,
59537 + pTun->StaticPathName) == 0)
59539 + if(GetTunnelHops(pTunnelIdList,&ErHops2BeAvoidedNumber,&ErHops2BeAvoided) != E_OK)
59541 + zlog_err("\ncannot get tunnel's hops %x %x %x %s %d",
59542 + rsvp_k.Session.Dest,
59543 + pTunnelIdList->tunnel_id,
59544 + rsvp_k.Session.ExtTunelId,
59545 + __FILE__,__LINE__);
59546 + ErHops2BeAvoidedNumber = 0;
59547 + ErHops2BeAvoided = NULL;
59549 + break;
59552 + else
59554 + zlog_err("\ncannot get Tunnel %x %x %x %s %d",
59555 + rsvp_k.Session.Dest,
59556 + pTunnelIdList->tunnel_id,
59557 + rsvp_k.Session.ExtTunelId,
59558 + __FILE__,__LINE__);
59560 + pTunnelIdList = pTunnelIdList->next;
59563 +#endif
59564 + pCall = LspRequest(pOpenLspParams,ErHops2BeAvoidedNumber,ErHops2BeAvoided,pSm,&pTunnel,TRUE,pParams);
59565 + strcpy(pTunnel->StaticPathName,pUserLsp->params.Primary);
59566 + StartLspSetupRetryTimer(pUserLsp->params.retry_timer,&pUserLsp->params.retry_count,pTunnel);
59567 + zlog_info("leaving LspSetupRetryExpiry");
59568 + return pCall;
59571 +void TearDownAndRemoveSecondary(USER_LSP *pCurrentUserLsp,char *PathName)
59573 + RSVP_TUNNEL_PROPERTIES *pTunnel = pCurrentUserLsp->pUserLspTunnels,*pTunnelPrev = NULL;
59575 + zlog_info("entering TearDownAndRemoveSecondary");
59577 + if(pTunnel == NULL)
59579 + zlog_err("\nTunnelIDList is empty %s %d",__FILE__,__LINE__);
59580 + return;
59582 + pTunnelPrev = pTunnel;
59583 + pTunnel = pTunnel->next_user_lsp_tunnel;
59584 + while(pTunnel != NULL)
59586 + if(strcmp(pTunnel->StaticPathName,PathName) == 0)
59588 + pTunnelPrev->next_user_lsp_tunnel = pTunnel->next_user_lsp_tunnel;
59589 + if(RsvpTunnelTearDown(pTunnel,
59590 + pCurrentUserLsp->params.to,
59591 + pCurrentUserLsp->params.from) != E_OK)
59593 + zlog_err("\ncannot tear donw the tunnel %s %d",__FILE__,__LINE__);
59595 + return;
59597 + pTunnelPrev = pTunnel;
59598 + pTunnel = pTunnel->next_user_lsp_tunnel;
59600 + zlog_info("leaving TearDownAndRemoveSecondary");
59603 +void CalculateUnneededPathAndTearDown(USER_LSP *pUserLsp,USER_LSP *pCurrentUserLsp)
59605 + SECONDARY_PATH_LIST *pSecList,*pSecList2,*pSecListPrev,*pSecListNext,*pSecListPrev2;
59606 + uns32 SecTunnelsCount = 0,SecPathCount = 0,SecTunnels2BeTorn = 0;
59607 + BOOL Found;
59608 + RSVP_TUNNEL_PROPERTIES *pTunnel;
59610 + zlog_info("entering CalculateUnneededPathAndTearDown");
59613 + pSecList = pUserLsp->params.SecondaryPaths;
59614 + pSecListPrev = NULL;
59615 + while(pSecList != NULL)
59617 + zlog_info("Received: %s %s",pSecList->Secondary,(pSecList->SecondaryPathParams) ? ((pSecList->SecondaryPathParams->disable) ? "is disabled" : "") : "");
59618 + pSecListNext = pSecList->next;
59619 + if((pSecList->SecondaryPathParams != NULL)&&
59620 + (pSecList->SecondaryPathParams->disable == TRUE))
59622 + pSecList2 = pCurrentUserLsp->params.SecondaryPaths;
59623 + pSecListPrev2 = NULL;
59624 + while(pSecList2 != NULL)
59626 + zlog_info("Exists: %s",pSecList2->Secondary);
59627 + if(strcmp(pSecList2->Secondary,pSecList->Secondary) == 0)
59629 + break;
59631 + pSecListPrev2 = pSecList2;
59632 + pSecList2 = pSecList2->next;
59634 + if(pSecList2 != NULL)
59636 + if(pSecListPrev2 == NULL)
59638 + pCurrentUserLsp->params.SecondaryPaths = pCurrentUserLsp->params.SecondaryPaths->next;
59640 + else
59642 + pSecListPrev2->next = pSecList2->next;
59644 + XFREE(MTYPE_TE,pSecList2->SecondaryPathParams);
59645 + XFREE(MTYPE_TE,pSecList2);
59647 + if(pSecListPrev == NULL)
59649 + pUserLsp->params.SecondaryPaths = pUserLsp->params.SecondaryPaths->next;
59651 + else
59653 + pSecListPrev->next = pSecList->next;
59655 + XFREE(MTYPE_TE,pSecList->SecondaryPathParams);
59656 + XFREE(MTYPE_TE,pSecList);
59658 + else
59660 + pSecListPrev = pSecList;
59662 + pSecList = pSecListNext;
59665 + /* find all the secondary LSPs (hot-standby) that must be established */
59666 + if(pCurrentUserLsp->pUserLspTunnels == NULL)
59668 + zlog_err("\nFirst Tunnel ID is NULL %s %d %s",__FILE__,__LINE__,pCurrentUserLsp->params.LspName);
59669 + return;
59671 + pTunnel = pCurrentUserLsp->pUserLspTunnels->next_user_lsp_tunnel;
59672 + /* First - count all the secondary tunnels */
59673 + while(pTunnel != NULL)
59675 + SecTunnelsCount++;
59676 + pTunnel = pTunnel->next_user_lsp_tunnel;
59678 + /* Second - count all the secondary hot-standby paths for new request */
59679 + pSecList = pUserLsp->params.SecondaryPaths;
59680 + while(pSecList != NULL)
59682 + if((pSecList->SecondaryPathParams != NULL)&&
59683 + (pSecList->SecondaryPathParams->standby == TRUE))
59685 + SecPathCount++;
59687 + pSecList = pSecList->next;
59690 + if(SecPathCount >= SecTunnelsCount)
59692 + zlog_info("SecPathCount %d SecTunnelsCount %d",SecPathCount,SecTunnelsCount);
59693 + return; /* There is no "spare" secondary tunnels */
59696 + /* How many tunnels should be torn down */
59697 + SecTunnels2BeTorn = SecTunnelsCount - SecPathCount;
59699 + /* set to the start of the list */
59700 + pTunnel = pCurrentUserLsp->pUserLspTunnels->next_user_lsp_tunnel;
59702 + /* Tear down the calculated number of tunnels */
59703 + /* Keep tunnels, passing over secondary paths of the new request */
59704 + while((pTunnel != NULL)&&(SecTunnels2BeTorn > 0))
59706 + pSecList = pUserLsp->params.SecondaryPaths;
59707 + Found = FALSE;
59708 + while(pSecList != NULL)
59710 + if((pSecList->SecondaryPathParams != NULL)&&
59711 + (pSecList->SecondaryPathParams->standby == TRUE))
59713 + if(strcmp(pSecList->Secondary,pTunnel->StaticPathName) == 0)
59715 + Found = TRUE;
59716 + break;
59719 + pSecList = pSecList->next;
59721 + if(Found == FALSE)
59723 + TearDownAndRemoveSecondary(pCurrentUserLsp,pTunnel->StaticPathName);
59724 + SecTunnels2BeTorn--;
59726 + pTunnel = pTunnel->next_user_lsp_tunnel;
59728 + zlog_info("leaving CalculateUnneededPathAndTearDown");
59731 +SM_CALL_T *PrepareAndIssueCrResolutionRequest(INGRESS_API *pOpenLspParams,
59732 + uns32 AvoidHopNumber,
59733 + IPV4_ADDR *AvoidHopsArray,
59734 + RSVP_TUNNEL_PROPERTIES *pTunnel,
59735 + SM_T *pSm,
59736 + LSP_PATH_SHARED_PARAMS *pParams)
59738 + CONSTRAINT_ROUTE_RESOLUTION_ARGS *pCrArgs;
59739 + SM_CALL_T *pCall = NULL;
59740 + zlog_info("entering PrepareAndIssueCrResolutionRequest");
59741 + if((pCrArgs = (CONSTRAINT_ROUTE_RESOLUTION_ARGS *)XMALLOC(MTYPE_TE,sizeof(CONSTRAINT_ROUTE_RESOLUTION_ARGS))) == NULL)
59743 + zlog_err("malloc failed %s %d",__FILE__,__LINE__);
59744 + LspSmDestroy(pSm);
59745 + return NULL;
59747 + pCrArgs->BW = pOpenLspParams->BW;
59748 + pCrArgs->ExclColorMask = pOpenLspParams->ExcludeAny;
59749 + pCrArgs->InclAnyColorMask = pOpenLspParams->IncludeAny;
59750 + pCrArgs->InclColorMask = pOpenLspParams->IncludeAll;
59751 + zlog_info("preparing CR request1");
59752 + if(pOpenLspParams->HopNum != 0)
59754 + pCrArgs->dest = pOpenLspParams->Path[0].IpAddr;
59756 + else
59757 + pCrArgs->dest = pOpenLspParams->Egress;
59758 + zlog_info("preparing CR request2 dest %x hop %x %x",pCrArgs->dest,pOpenLspParams->HopNum,pOpenLspParams->Path[0].IpAddr);
59759 + pCrArgs->PsbKey.Session.Dest = pOpenLspParams->Egress;
59760 + pCrArgs->PsbKey.Session.TunnelId = pOpenLspParams->TunnelId;
59761 + pCrArgs->PsbKey.Session.ExtTunelId = pOpenLspParams->src_ip;
59762 + pCrArgs->AvoidHopNumber = AvoidHopNumber;
59763 + pCrArgs->AvoidHopsArray = AvoidHopsArray;
59764 + if(GetAlreadyAllocatedBW(pTunnel,&pCrArgs->pLinkBw,&pCrArgs->LinkBwNumber,pCrArgs->BW) != E_OK)
59766 + zlog_err("Cannot get Link BW");
59768 + if(pOpenLspParams->ErHops2Exclude[0] != 0)
59770 + if(pOpenLspParams->ErHops2Exclude[1] != 0)
59772 + pCrArgs->ExcludeHopNumber = 2;
59774 + else
59776 + pCrArgs->ExcludeHopNumber = 1;
59779 + if((pCrArgs->ExcludeHopsArray = (IPV4_ADDR *)XMALLOC(MTYPE_TE,sizeof(IPV4_ADDR)*(pCrArgs->ExcludeHopNumber))) != NULL)
59781 + memcpy(pCrArgs->ExcludeHopsArray,
59782 + pOpenLspParams->ErHops2Exclude,
59783 + sizeof(IPV4_ADDR)*(pCrArgs->ExcludeHopNumber));
59787 + pCrArgs->SetupPriority = pOpenLspParams->SetPrio;
59788 + pCrArgs->HoldPriority = pOpenLspParams->HoldPrio;
59789 + if(pParams != NULL)
59791 + pCrArgs->HopCount = pParams->hop_limit;
59793 + else
59795 + pCrArgs->HopCount = 0;
59797 + zlog_info("HOP COUNT#%d",pCrArgs->HopCount);
59798 + if(pTunnel->pOpenLspParams != NULL)
59800 + zlog_info("%s %d",__FILE__,__LINE__);
59801 + XFREE(MTYPE_TE,pTunnel->pOpenLspParams);
59803 + zlog_info("%s %d",__FILE__,__LINE__);
59804 + pTunnel->pOpenLspParams = pOpenLspParams;
59805 + if(pTunnel->pCrArgs != NULL)
59807 + if((((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->tunneled == FALSE)&&
59808 + (((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->data.path.ErHopNumber != 0))
59810 + XFREE(MTYPE_TE,((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->data.path.pErHop);
59812 + if(((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->AvoidHopNumber != 0)
59814 + XFREE(MTYPE_TE,((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->AvoidHopsArray);
59816 + if(((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->ExcludeHopNumber != 0)
59818 + XFREE(MTYPE_TE,((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->ExcludeHopsArray);
59820 + if(((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->LinkBwNumber)
59822 + XFREE(MTYPE_TE,((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->pLinkBw);
59824 + XFREE(MTYPE_TE,pTunnel->pCrArgs);
59826 + pTunnel->pCrArgs = pCrArgs;
59828 + if(StartCspfRetryTimer(pTunnel) != E_OK)
59830 + zlog_err("Cannot start CSPF retry timer");
59832 + UnregisterClient((int)pSm,pOpenLspParams->TunnelId);
59834 + zlog_info("preparing CR request5");
59835 + if((pCall = constraint_route_resolution_sm_invoke(pSm,
59836 + pCrArgs)) == NULL)
59838 + zlog_err("cannot invoke constraint route resolution");
59839 + XFREE(MTYPE_TE,pCrArgs);
59840 + LspSmDestroy(pSm);
59841 + return NULL;
59843 + zlog_info("leaving PrepareAndIssueCrResolutionRequest");
59844 + return pCall;
59847 +SM_CALL_T *LspRequest(INGRESS_API *pOpenLspParams,
59848 + uns32 ExcludeHopNumber,
59849 + IPV4_ADDR *ExcludeHopsArray,
59850 + SM_T *pSm,
59851 + RSVP_TUNNEL_PROPERTIES **ppTunnel,
59852 + BOOL ForceCrResolution,
59853 + LSP_PATH_SHARED_PARAMS *pParams)
59855 + SM_CALL_T *pCall = NULL;
59856 + PSB_KEY PsbKey;
59857 + RSVP_TUNNEL_PROPERTIES *pTunnel;
59859 + zlog_info("entering LspRequest");
59861 + memset(&PsbKey,0,sizeof(PSB_KEY));
59862 + PsbKey.Session.Dest = pOpenLspParams->Egress;
59863 + PsbKey.Session.TunnelId = pOpenLspParams->TunnelId;
59864 + PsbKey.Session.ExtTunelId = pOpenLspParams->src_ip;
59866 + if(FindTunnel(&PsbKey,&pTunnel,ALL_TRUNKS) != TRUE)
59868 + TRUNK_TYPE trunk_type;
59869 + if(pOpenLspParams->sm_handle != 0)
59871 + switch(((SM_T *)pOpenLspParams->sm_handle)->sm_type)
59873 + default:
59874 + trunk_type = SEPARATE_NON_ADAPTIVE;
59877 + else
59879 + trunk_type = SEPARATE_NON_ADAPTIVE;
59881 + if(NewTunnel(&PsbKey,&pTunnel,trunk_type) != E_OK)
59883 + zlog_err("cannot create new tunnel's structure");
59884 + LspSmDestroy(pSm);
59885 + return NULL;
59887 + if(pOpenLspParams->sm_handle != 0)
59889 + switch(((SM_T *)pOpenLspParams->sm_handle)->sm_type)
59891 + case FAST_REROUTE_SM:
59892 + pTunnel->up_sm_handle = (void *)pOpenLspParams->sm_handle;
59893 + break;
59894 + default:
59898 + *ppTunnel = pTunnel;
59899 + pTunnel->RequiredBW = pOpenLspParams->BW;
59900 + pTunnel->sm_handle = pSm;
59902 + return PrepareAndIssueCrResolutionRequest(pOpenLspParams,
59903 + ExcludeHopNumber,
59904 + ExcludeHopsArray,
59905 + pTunnel,
59906 + pSm,
59907 + pParams);
59909 + else if(pOpenLspParams->HopNum != 0) /* Possible REROUTE */
59911 + *ppTunnel = pTunnel;
59912 + pTunnel->RequiredBW = pOpenLspParams->BW;
59913 + pTunnel->sm_handle = pSm;
59914 + return PrepareAndIssueCrResolutionRequest(pOpenLspParams,
59915 + ExcludeHopNumber,
59916 + ExcludeHopsArray,
59917 + pTunnel,
59918 + pSm,
59919 + pParams);
59921 + else
59923 + RSVP_LSP_PROPERTIES *pRsvpLsp = GetWorkingRsvpLsp(pTunnel);
59925 + *ppTunnel = pTunnel;
59927 + pTunnel->sm_handle = pSm;
59929 + /* BW DECREASE OPERATION */
59930 + if(pTunnel->RequiredBW > pOpenLspParams->BW)
59932 + /* For tunneled LSPs */
59933 + if((pRsvpLsp != NULL)&&
59934 + (pRsvpLsp->tunneled == TRUE))
59936 + /* invoke lsp sm for the tunnel */
59939 + NotifySatisfiedRequests(pTunnel);
59942 + if(ForceCrResolution == TRUE)
59944 + pTunnel->RequiredBW = pOpenLspParams->BW;
59945 + return PrepareAndIssueCrResolutionRequest(pOpenLspParams,
59946 + ExcludeHopNumber,
59947 + ExcludeHopsArray,
59948 + pTunnel,
59949 + pSm,
59950 + pParams);
59952 + else
59954 + if(NewRsvpLspRequired(pTunnel,pOpenLspParams) == TRUE)
59956 + if(((pRsvpLsp != NULL)&&(pRsvpLsp->RequestedBW >= pOpenLspParams->BW))||(pRsvpLsp == NULL))
59958 + pTunnel->pOpenLspParams = pOpenLspParams;
59959 + if(CreateAndInvokeRsvpLsp(pTunnel,
59960 + pRsvpLsp,
59961 + FALSE,
59962 + NULL) != E_OK)
59964 + zlog_err("cannot modify LSP %s %d",__FILE__,__LINE__);
59967 + else
59969 + RSVP_LSP_PROPERTIES *pRsvpLsp2TakePath;
59970 + if((pRsvpLsp2TakePath = FindRsvpLspPathWithBW(pTunnel,pOpenLspParams->BW)) == NULL)
59972 + zlog_err("unexpected: cannot find path with BW %s %d",__FILE__,__LINE__);
59973 + return NULL;
59975 + pTunnel->pOpenLspParams = pOpenLspParams;
59976 + if(CreateAndInvokeRsvpLsp(pTunnel,
59977 + pRsvpLsp2TakePath,
59978 + FALSE,
59979 + NULL) != E_OK)
59981 + zlog_err("cannot modify LSP %s %d",__FILE__,__LINE__);
59984 + pTunnel->RequiredBW = pOpenLspParams->BW;
59988 + else /* BW INCREASE OPERATION */
59990 + RSVP_LSP_PROPERTIES *pWorkingRsvpLsp;
59992 + if((pRsvpLsp != NULL)&&
59993 + (pRsvpLsp->tunneled == TRUE))
59995 + return PrepareAndIssueCrResolutionRequest(pOpenLspParams,
59996 + ExcludeHopNumber,
59997 + ExcludeHopsArray,
59998 + pTunnel,
59999 + pSm,
60000 + pParams);
60003 + if(((pWorkingRsvpLsp = CurrentPathHasAvBw(pTunnel,pOpenLspParams->BW)) != NULL)&&
60004 + (ForceCrResolution == FALSE))
60006 + int i;
60007 + zlog_info("Path is extendable.");
60008 + /* pRsvpLsp's path is choosen */
60009 + pOpenLspParams->HopNum = pWorkingRsvpLsp->forw_info.path.HopCount;
60010 + for(i = 0;i < pOpenLspParams->HopNum;i++)
60012 + pOpenLspParams->Path[i].Loose = 0;
60013 + pOpenLspParams->Path[i].IpAddr = pWorkingRsvpLsp->forw_info.path.pErHopsList[i];
60014 + pOpenLspParams->Path[i].PrefixLength = 32;
60017 + pTunnel->RequiredBW = pOpenLspParams->BW;
60018 + zlog_info("Issuing CR Resolution request...");
60019 + return PrepareAndIssueCrResolutionRequest(pOpenLspParams,
60020 + ExcludeHopNumber,
60021 + ExcludeHopsArray,
60022 + pTunnel,
60023 + pSm,
60024 + pParams);
60027 + return pCall;
60030 +BOOL NewRsvpLspRequired(RSVP_TUNNEL_PROPERTIES *pTunnel,INGRESS_API *pOpenLspParams)
60032 + RSVP_LSP_PROPERTIES *pRsvpLsp = pTunnel->properties;
60034 + zlog_info("entering NewRsvpLspRequired");
60036 + while(pRsvpLsp != NULL)
60038 + if(pRsvpLsp->RequestedBW == pOpenLspParams->BW)
60040 + zlog_info("leaving NewRsvpLspRequired");
60041 + return FALSE;
60043 + pRsvpLsp = pRsvpLsp->next;
60045 + zlog_info("leaving NewRsvpLspRequired");
60046 + return TRUE;
60049 +RSVP_LSP_PROPERTIES *FindRsvpLspPathWithBW(RSVP_TUNNEL_PROPERTIES *pTunnel,float BW)
60051 + float TempBW = 0xFFFFFFFF; /* FIXME*/
60052 + RSVP_LSP_PROPERTIES *pRsvpLsp = pTunnel->properties,*pSelectedRsvpLsp = NULL;
60054 + zlog_info("entering FindRsvpLspPathWithBW");
60056 + while(pRsvpLsp != NULL)
60058 + if(pRsvpLsp->RequestedBW >= BW)
60060 + if(pRsvpLsp->RequestedBW < TempBW)
60062 + pSelectedRsvpLsp = pRsvpLsp;
60063 + TempBW = pRsvpLsp->RequestedBW;
60066 + pRsvpLsp = pRsvpLsp->next;
60068 + zlog_info("leaving FindRsvpLspPathWithBW");
60069 + return pSelectedRsvpLsp;
60072 +void NotifySatisfiedRequests(RSVP_TUNNEL_PROPERTIES *pTunnel)
60074 + zlog_info("entering NotifySatisfiedRequests");
60075 + if(pTunnel->up_sm_handle != 0)
60077 + if(sm_gen_async_event_send(pTunnel->up_sm_handle,INGRESS_LSP_OPERATION_COMPLETE_EVENT,NULL) != 0)
60079 + zlog_err("\ncannot send async event %s %d",__FILE__,__LINE__);
60082 + zlog_info("leaving NotifySatisfiedRequests");
60085 +void NotifyFailedRequests(RSVP_TUNNEL_PROPERTIES *pTunnel)
60087 + zlog_info("entering NotifyFailedRequests");
60089 + if(pTunnel->up_sm_handle != 0)
60091 + if(sm_gen_async_event_send(pTunnel->up_sm_handle,INGRESS_LSP_OPERATION_FAILED_EVENT,NULL) != 0)
60093 + zlog_err("\ncannot send async event %s %d",__FILE__,__LINE__);
60096 + zlog_info("leaving NotifyFailedRequests");
60099 +uns16 NewRsvpLspId(RSVP_TUNNEL_PROPERTIES *pTunnel)
60101 + if(pTunnel->LastInvokedLspId == 0xFFFF)
60102 + pTunnel->LastInvokedLspId = 1;
60103 + else
60104 + pTunnel->LastInvokedLspId++;
60105 + return pTunnel->LastInvokedLspId;
60108 +uns32 CopyRsvpLspPath(RSVP_LSP_PROPERTIES *pRsvpLsp,INGRESS_API *pOpenRsvpLsp)
60110 + zlog_info("entering CopyRsvpLspPath");
60111 + if(pOpenRsvpLsp->HopNum != 0)
60113 + IPV4_ADDR *pArray;
60114 + int i;
60116 + if((pArray = (IPV4_ADDR *)XMALLOC(MTYPE_TE,sizeof(IPV4_ADDR)*pOpenRsvpLsp->HopNum)) == NULL)
60118 + zlog_err("\nmalloc failed %s %d",__FILE__,__LINE__);
60119 + return E_ERR;
60122 + for(i = 0;i < pOpenRsvpLsp->HopNum;i++)
60124 + *(pArray + i) = pOpenRsvpLsp->Path[i].IpAddr;
60126 + pRsvpLsp->forw_info.path.pErHopsList = pArray;
60128 + else
60129 + pRsvpLsp->forw_info.path.pErHopsList = NULL;
60130 + pRsvpLsp->forw_info.path.HopCount = pOpenRsvpLsp->HopNum;
60131 + pRsvpLsp->oIfIndex = pOpenRsvpLsp->OutIfIndex;
60132 + zlog_info("leaving CopyRsvpLspPath");
60133 + return E_OK;
60136 +RSVP_LSP_PROPERTIES *GetWorkingRsvpLsp(RSVP_TUNNEL_PROPERTIES *pTunnel)
60138 + RSVP_LSP_PROPERTIES *pRsvpLsp = pTunnel->properties;
60140 + zlog_info("entering GetWorkingRsvpLsp");
60142 + while(pRsvpLsp != NULL)
60144 + if(pRsvpLsp->LspId == pTunnel->LspId)
60145 + return pRsvpLsp;
60146 + pRsvpLsp = pRsvpLsp->next;
60148 + zlog_info("leaving GetWorkingRsvpLsp");
60149 + return NULL;
60152 +uns32 CopyWorkingPath(RSVP_LSP_PROPERTIES *pDestRsvpLsp,RSVP_LSP_PROPERTIES *pSourceRsvpLsp)
60154 + IPV4_ADDR *pArray;
60155 + int i;
60157 + zlog_info("entering CopyWorkingPath");
60159 + if((pArray = (IPV4_ADDR *)XMALLOC(MTYPE_TE,sizeof(IPV4_ADDR)*pSourceRsvpLsp->forw_info.path.HopCount)) == NULL)
60161 + zlog_err("\nmalloc failed %s %d",__FILE__,__LINE__);
60162 + return E_ERR;
60165 + for(i = 0;i < pSourceRsvpLsp->forw_info.path.HopCount;i++)
60167 + *(pArray + i) = pSourceRsvpLsp->forw_info.path.pErHopsList[i];
60169 + pDestRsvpLsp->forw_info.path.pErHopsList = pArray;
60170 + pDestRsvpLsp->forw_info.path.HopCount = pSourceRsvpLsp->forw_info.path.HopCount;
60171 +// pDestRsvpLsp->card = pSourceRsvpLsp->card;
60172 + pDestRsvpLsp->oIfIndex = pSourceRsvpLsp->oIfIndex;
60173 + zlog_info("leaving CopyWorkingPath");
60174 + return E_OK;
60177 +BOOL IdenticalRsvpLspExists(RSVP_TUNNEL_PROPERTIES *pTunnel,RSVP_LSP_PROPERTIES *pThisRsvpLsp,uns16 *LspDiffPathSameParams)
60179 + RSVP_LSP_PROPERTIES *pRsvpLsp = pTunnel->properties;
60181 + zlog_info("entering IdenticalRsvpLspExists");
60183 + while(pRsvpLsp != NULL)
60185 + if(pRsvpLsp->LspId != pThisRsvpLsp->LspId)
60187 + if((pRsvpLsp->RequestedBW == pThisRsvpLsp->RequestedBW)&&
60188 + //(pRsvpLsp->card == pThisRsvpLsp->card)&&
60189 + (pRsvpLsp->oIfIndex == pThisRsvpLsp->oIfIndex)&&
60190 + (pRsvpLsp->SetupPriority == pThisRsvpLsp->SetupPriority)&&
60191 + (pRsvpLsp->HoldPriority == pThisRsvpLsp->HoldPriority)&&
60192 + (pRsvpLsp->ExcludeAny == pThisRsvpLsp->ExcludeAny)&&
60193 + (pRsvpLsp->IncludeAny == pThisRsvpLsp->IncludeAny)&&
60194 + (pRsvpLsp->IncludeAll == pThisRsvpLsp->IncludeAll)&&
60195 + (pRsvpLsp->FrrDesired == pThisRsvpLsp->FrrDesired)&&
60196 + (pRsvpLsp->LabelRecordingDesired == pThisRsvpLsp->LabelRecordingDesired))
60198 + *LspDiffPathSameParams = pRsvpLsp->LspId;
60199 + if((pRsvpLsp->tunneled == FALSE)&&
60200 + (pThisRsvpLsp->tunneled == FALSE))
60202 + if((pRsvpLsp->forw_info.path.HopCount == pThisRsvpLsp->forw_info.path.HopCount)&&
60203 + (memcmp(pRsvpLsp->forw_info.path.pErHopsList,
60204 + pThisRsvpLsp->forw_info.path.pErHopsList,
60205 + sizeof(IPV4_ADDR)*(pRsvpLsp->forw_info.path.HopCount)) == 0))
60207 + return TRUE;
60210 + else if((pRsvpLsp->tunneled == TRUE)&&
60211 + (pThisRsvpLsp->tunneled == TRUE))
60213 + if(memcmp(&pRsvpLsp->forw_info.tunnel,&pThisRsvpLsp->forw_info.tunnel,sizeof(PSB_KEY)) == 0)
60215 + return TRUE;
60220 + pRsvpLsp = pRsvpLsp->next;
60222 + zlog_info("leaving IdenticalRsvpLspExists");
60223 + return FALSE;
60226 +void UpdatePathBW(RSVP_TUNNEL_PROPERTIES *pTunnel,RSVP_LSP_PROPERTIES *pCurrentRsvpLsp,IPV4_ADDR dest)
60228 + RSVP_LSP_PROPERTIES *pRsvpLsp = pTunnel->properties;
60229 + uns16 LspId = pCurrentRsvpLsp->LspId;
60230 + float *BWs;
60231 + int lsp_hop_index,curr_lsp_hop_index,number_of_links,i;
60232 + IPV4_ADDR lsp_local_ip,lsp_remote_ip,current_lsp_local_ip,current_lsp_remote_ip;
60234 + zlog_info("entering UpdatePathBW");
60236 + if(pRsvpLsp->tunneled == TRUE)
60238 + return;
60240 + number_of_links = pCurrentRsvpLsp->forw_info.path.HopCount / 2;
60241 + if((BWs = (float *)XMALLOC(MTYPE_TE,sizeof(float)*(number_of_links))) == NULL)
60243 + zlog_err("\nmalloc failed %s %d",__FILE__,__LINE__);
60244 + return;
60247 + while(pRsvpLsp != NULL)
60249 + if((pRsvpLsp->LspId != LspId)&&
60250 + (pRsvpLsp->tunneled == FALSE)&&
60251 + (pRsvpLsp->HoldPriority <= pCurrentRsvpLsp->HoldPriority))
60253 + for(lsp_hop_index = 1;
60254 + lsp_hop_index < pRsvpLsp->forw_info.path.HopCount;
60255 + lsp_hop_index += 2)
60257 + for(curr_lsp_hop_index = 1,i = 0;
60258 + (curr_lsp_hop_index < (pCurrentRsvpLsp->forw_info.path.HopCount - 1))&&(i < number_of_links);
60259 + curr_lsp_hop_index += 2,i++)
60261 + lsp_local_ip = pRsvpLsp->forw_info.path.pErHopsList[lsp_hop_index];
60262 + current_lsp_local_ip = pCurrentRsvpLsp->forw_info.path.pErHopsList[curr_lsp_hop_index];
60263 + if(lsp_local_ip == current_lsp_local_ip)
60265 + lsp_remote_ip = pRsvpLsp->forw_info.path.pErHopsList[lsp_hop_index + 1];
60266 + current_lsp_remote_ip = pCurrentRsvpLsp->forw_info.path.pErHopsList[curr_lsp_hop_index + 1];
60267 + if(lsp_remote_ip == current_lsp_remote_ip)
60269 + if(BWs[i] < pRsvpLsp->RequestedBW)
60271 + BWs[i] = pRsvpLsp->RequestedBW;
60278 + pRsvpLsp = pRsvpLsp->next;
60280 + for(curr_lsp_hop_index = 1,i = 0;
60281 + (curr_lsp_hop_index < (pCurrentRsvpLsp->forw_info.path.HopCount - 1))&&(i < number_of_links);
60282 + curr_lsp_hop_index += 2,i++)
60284 + if(BWs[i] < pCurrentRsvpLsp->RequestedBW)
60286 + IPV4_ADDR *pIpAddrArray = pCurrentRsvpLsp->forw_info.path.pErHopsList;
60287 + IPV4_ADDR remote_ip = pIpAddrArray[curr_lsp_hop_index + 1];
60288 + if(pIpAddrArray[curr_lsp_hop_index] != remote_ip)
60290 + zlog_info("Updating BW#%f Local IP#%x Remote IP#%x",
60291 + pCurrentRsvpLsp->RequestedBW - BWs[i],
60292 + pCurrentRsvpLsp->forw_info.path.pErHopsList[curr_lsp_hop_index],
60293 + pCurrentRsvpLsp->forw_info.path.pErHopsList[curr_lsp_hop_index + 1]);
60294 + if(rdb_remote_link_bw_update(pCurrentRsvpLsp->forw_info.path.pErHopsList[curr_lsp_hop_index],
60295 + pCurrentRsvpLsp->forw_info.path.pErHopsList[curr_lsp_hop_index + 1],
60296 + pCurrentRsvpLsp->RequestedBW - BWs[i],
60297 + pCurrentRsvpLsp->HoldPriority, /* SHOULD BE CHECKED!!!*/
60298 + PSC_PATH) != E_OK)
60300 + zlog_err("\ncannot update remote link %s %d",__FILE__,__LINE__);
60305 + zlog_info("leaving UpdatePathBW");
60306 + XFREE(MTYPE_TE,BWs);
60309 +static E_RC GetAlreadyAllocatedBW(RSVP_TUNNEL_PROPERTIES *pTunnel,void **ppLinkBw,uns32 *LinkBwNumber,float CommonBwValue)
60311 + RSVP_LSP_PROPERTIES *pRsvpLsp;
60312 + LINK_BW *pLinkBw;
60313 + int curr_lsp_hop_index,i,number_of_links;
60314 + float Bw;
60315 + zlog_info("entering GetAlreadyAllocatedBW");
60316 + *ppLinkBw = NULL;
60317 + if((pRsvpLsp = GetWorkingRsvpLsp(pTunnel)) == NULL)
60319 + return E_OK;
60321 + if(pRsvpLsp->tunneled)
60323 + return E_OK;
60325 + if(pRsvpLsp->forw_info.path.HopCount < 2)
60327 + return E_OK;
60329 + number_of_links = pRsvpLsp->forw_info.path.HopCount / 2;
60330 + if((pLinkBw = XMALLOC(MTYPE_TE,sizeof(LINK_BW)*(number_of_links))) == NULL)
60332 + zlog_err("Memory allocation failed %s %d",__FILE__,__LINE__);
60333 + return E_ERR;
60335 + if(pRsvpLsp->RequestedBW < CommonBwValue)
60337 + Bw = CommonBwValue - pRsvpLsp->RequestedBW;
60339 + else
60341 + Bw = 0;
60343 + for(curr_lsp_hop_index = 1,i = 0;
60344 + (curr_lsp_hop_index < pRsvpLsp->forw_info.path.HopCount)&&(i < number_of_links);
60345 + curr_lsp_hop_index += 2,i++)
60347 + pLinkBw[i].LocalIp.s_addr = pRsvpLsp->forw_info.path.pErHopsList[curr_lsp_hop_index];
60348 + pLinkBw[i].RemoteIp.s_addr = pRsvpLsp->forw_info.path.pErHopsList[curr_lsp_hop_index + 1];
60349 + pLinkBw[i].Bw = Bw;
60351 + *ppLinkBw = pLinkBw;
60352 + *LinkBwNumber = number_of_links;
60353 + zlog_info("leaving GetAlreadyAllocatedBW");
60354 + return E_OK;
60357 +uns32 CreateAndInvokeRsvpLsp(RSVP_TUNNEL_PROPERTIES *pTunnel,
60358 + RSVP_LSP_PROPERTIES *pRsvpLsp2TakePath,
60359 + BOOL tunneled,
60360 + PSB_KEY *PsbKey)
60362 + RSVP_LSP_PROPERTIES *pRsvpLsp = NULL,*pRsvpWorkingLsp = NULL;
60363 + uns16 LspId = 0;
60364 + TE_API_MSG Msg;
60365 + INGRESS_API *pOpenRsvpLsp;
60366 + uns16 LspDiffPathSameParams = 0,RemoveLspAndExit = 0;
60367 + USER_LSP *pUserLsp;
60369 + zlog_info("entering CreateAndInvokeRsvpLsp");
60371 + pOpenRsvpLsp = pTunnel->pOpenLspParams;
60373 + LspId = NewRsvpLspId(pTunnel);
60375 + if(NewRsvpLsp(pTunnel,&pRsvpLsp) != E_OK)
60377 + zlog_err("\ncannot create and invoke RSVP LSP %s %d",__FILE__,__LINE__);
60378 + return E_ERR;
60380 + pRsvpLsp->RequestedBW = pOpenRsvpLsp->BW;
60382 + pRsvpLsp->LspId = LspId;
60383 + zlog_info("\nTunnel # %x LSP # %x",pTunnel->TunnelId,pRsvpLsp->LspId);
60384 + pOpenRsvpLsp->LspId = LspId;
60386 + pRsvpLsp->SetupPriority = pOpenRsvpLsp->SetPrio;
60387 + pRsvpLsp->HoldPriority = pOpenRsvpLsp->HoldPrio;
60388 + pRsvpLsp->ExcludeAny = pOpenRsvpLsp->ExcludeAny;
60389 + pRsvpLsp->IncludeAny = pOpenRsvpLsp->IncludeAny;
60390 + pRsvpLsp->IncludeAll = pOpenRsvpLsp->IncludeAll;
60391 + pRsvpLsp->FrrDesired = pOpenRsvpLsp->FrrDesired;
60392 + pRsvpLsp->LabelRecordingDesired = pOpenRsvpLsp->LabelRecordingDesired;
60394 + if(pRsvpLsp2TakePath == NULL)
60396 + if(tunneled == TRUE)
60398 + pRsvpLsp->tunneled = TRUE;
60399 + pRsvpLsp->forw_info.tunnel = *PsbKey;
60400 + pRsvpLsp->oIfIndex = pOpenRsvpLsp->OutIfIndex;
60401 + zlog_info("\nTunneled LSP: %x %x %x %x %x %x %x",
60402 + pOpenRsvpLsp->Egress,
60403 + pOpenRsvpLsp->TunnelId,
60404 + pOpenRsvpLsp->src_ip,
60405 + pOpenRsvpLsp->LspId,
60406 + pOpenRsvpLsp->OutIfIndex,
60407 + pOpenRsvpLsp->NextHop);
60409 + else if(CopyRsvpLspPath(pRsvpLsp,pOpenRsvpLsp) != E_OK)
60411 + zlog_err("\ncannot copy RSVP LSP path %s %d",__FILE__,__LINE__);
60412 + return E_ERR;
60415 + else
60417 + zlog_info("\ncopying working path");
60418 + if(CopyWorkingPath(pRsvpLsp,pRsvpLsp2TakePath) != E_OK)
60420 + zlog_err("\ncannot copy RSVP LSP path %s %d",__FILE__,__LINE__);
60421 + return E_ERR;
60423 + if(pRsvpLsp->tunneled == FALSE)
60425 + pOpenRsvpLsp->HopNum = pRsvpLsp->forw_info.path.HopCount;
60426 + if(pRsvpLsp->forw_info.path.HopCount != 0)
60428 + int i;
60429 + for(i = 0;i < pOpenRsvpLsp->HopNum;i++)
60431 + pOpenRsvpLsp->Path[i].Loose = 0;
60432 + pOpenRsvpLsp->Path[i].PrefixLength = 32;
60433 + pOpenRsvpLsp->Path[i].IpAddr = pRsvpLsp->forw_info.path.pErHopsList[i];
60435 + pOpenRsvpLsp->NextHop = pRsvpLsp->forw_info.path.pErHopsList[0];
60437 + else
60439 + zlog_info("\nER hops list is empty %s %d",__FILE__,__LINE__);
60441 + pOpenRsvpLsp->NextHop = pRsvpLsp->forw_info.path.pErHopsList[0];
60443 + else
60445 + pOpenRsvpLsp->NextHop = pRsvpLsp->forw_info.tunnel.Session.Dest;
60447 + pOpenRsvpLsp->OutIfIndex = pRsvpLsp->oIfIndex;
60450 + UpdatePathBW(pTunnel,pRsvpLsp,pOpenRsvpLsp->Egress);
60452 + if(IdenticalRsvpLspExists(pTunnel,pRsvpLsp,&LspDiffPathSameParams) == TRUE)
60454 + RemoveLspAndExit = 1;
60456 + else if(LspDiffPathSameParams)
60458 + if((pUserLsp = UserLspGet(pTunnel->UserLspName)) != NULL)
60460 + STATIC_PATH *pStaticPath;
60461 + if((pUserLsp->pUserLspTunnels != NULL)&&
60462 + (pTunnel->TunnelId != pUserLsp->pUserLspTunnels->TunnelId)&&
60463 + (rdb_get_static_path(pTunnel->StaticPathName,&pStaticPath) != E_OK))
60465 + IPV4_ADDR *pPrimaryErHops;
60466 + uns32 PrimaryErHopsNumber = 0;
60467 + RSVP_LSP_PROPERTIES *pClone = pTunnel->properties;
60468 + while(pClone != NULL)
60470 + if(pClone->LspId == LspDiffPathSameParams)
60472 + break;
60474 + pClone = pClone->next;
60476 + if((pClone != NULL)&&(!pClone->tunneled)&&(!pRsvpLsp->tunneled))
60478 + if(GetTunnelHops(pUserLsp->pUserLspTunnels,&PrimaryErHopsNumber,&pPrimaryErHops) == E_OK)
60480 + int i,j,ClonesSharedHopsCount = 0,ThisLspSharedHopsCount = 0;
60481 + if(pPrimaryErHops != NULL)
60483 + for(i = 0,j = 0;i < PrimaryErHopsNumber;i++,j += 2)
60485 + if(pPrimaryErHops[i] == pClone->forw_info.path.pErHopsList[j])
60487 + ClonesSharedHopsCount++;
60490 + for(i = 0,j = 0;i < PrimaryErHopsNumber;i++,j += 2)
60492 + if(pPrimaryErHops[i] == pRsvpLsp->forw_info.path.pErHopsList[j])
60494 + ThisLspSharedHopsCount++;
60497 + if(ThisLspSharedHopsCount >= ClonesSharedHopsCount)
60499 + RemoveLspAndExit = 1;
60501 + XFREE(MTYPE_TE,pPrimaryErHops);
60508 + if(RemoveLspAndExit)
60510 + RSVP_LSP_PROPERTIES *pTemp = pTunnel->properties,*pRsvpLspPrev = NULL;
60511 + while(pTemp != NULL)
60513 + if(pTemp == pRsvpLsp)
60515 + if(pTemp == pTunnel->properties)
60517 + pTunnel->properties = pTunnel->properties->next;
60519 + else
60521 + pRsvpLspPrev->next = pTemp->next;
60523 + if(pRsvpLsp->tunneled == FALSE)
60525 + if(pRsvpLsp->forw_info.path.pErHopsList != NULL)
60527 + XFREE(MTYPE_TE,pRsvpLsp->forw_info.path.pErHopsList);
60530 + XFREE(MTYPE_TE,pRsvpLsp);
60531 + if(pTunnel->adaptivity_timer.is_active == FALSE)
60533 + if((pUserLsp = UserLspGet(pTunnel->UserLspName)) != NULL)
60535 + LSP_PATH_SHARED_PARAMS *pParams;
60536 + pParams = PathParamsGet(pUserLsp,
60537 + pTunnel->StaticPathName,
60538 + ((!strcmp(pUserLsp->params.Primary,pTunnel->StaticPathName))&&(pUserLsp->pUserLspTunnels->TunnelId == pTunnel->TunnelId)));
60539 + StartAdaptivityTimer(pParams->optimize_timer,pTunnel);
60542 + return E_OK;
60544 + pRsvpLspPrev = pTemp;
60545 + pTemp = pTemp->next;
60548 + if(pRsvpLsp->tunneled == FALSE)
60550 + int i;
60551 + IPV4_ADDR *pIpAddr = pRsvpLsp->forw_info.path.pErHopsList;
60552 + zlog_info("\nPATH:");
60553 + for(i = 0;i < pRsvpLsp->forw_info.path.HopCount;i++)
60554 + zlog_info("\nER HOP#%d %x",i+1,pIpAddr[i]);
60556 + Msg.NotificationType = PATH_SEND_CMD;
60557 + memcpy(&Msg.u.IngressApi,pOpenRsvpLsp,sizeof(INGRESS_API));
60558 + if((pRsvpWorkingLsp = GetWorkingRsvpLsp(pTunnel)) != NULL)
60560 + if((pRsvpLsp->tunneled == FALSE)&&
60561 + (pRsvpWorkingLsp->tunneled == FALSE))
60563 + if(!((pRsvpLsp->forw_info.path.HopCount == pRsvpWorkingLsp->forw_info.path.HopCount)&&
60564 + (memcmp(pRsvpLsp->forw_info.path.pErHopsList,
60565 + pRsvpWorkingLsp->forw_info.path.pErHopsList,
60566 + sizeof(IPV4_ADDR)*(pRsvpLsp->forw_info.path.HopCount)) == 0)))
60567 + pTunnel->ReRoute = TRUE;
60570 + else
60572 + pTunnel->ReRoute = TRUE;
60574 + Msg.u.IngressApi.LspId = LspId;
60575 + Msg.u.IngressApi.NextHop = htonl(Msg.u.IngressApi.NextHop);
60577 + zlog_info("Next Hop %x OutIf %x %s %d",
60578 + Msg.u.IngressApi.NextHop,Msg.u.IngressApi.OutIfIndex,__FILE__,__LINE__);
60580 + te_send_msg(&Msg,sizeof(Msg));
60582 + StartLspSetupTimer(pTunnel);
60584 + if((pOpenRsvpLsp->FrrDesired)&&
60585 + (pRsvpLsp->tunneled == FALSE)&& /* if tunneled, the tunnel should be reestablished with local protection */
60586 + (pOpenRsvpLsp->HopNum > 1))
60588 + FRR_SM_CALL frr_sm_call;
60589 + int k;
60590 + IPV4_ADDR protected_node_router_id = 0,merge_node_router_id = 0,after_merge_node_router_id = 0;
60592 + memset(&frr_sm_call,0,sizeof(FRR_SM_CALL));
60593 + frr_sm_call.frr_key.OutIfIndex = pOpenRsvpLsp->OutIfIndex;
60595 + if(rdb_remote_link_router_id_get(pOpenRsvpLsp->NextHop,
60596 + &protected_node_router_id) != E_OK)
60598 + protected_node_router_id = pOpenRsvpLsp->NextHop;
60600 + frr_sm_call.frr_key.protected_node = protected_node_router_id;
60601 + for(k = 1;k < pOpenRsvpLsp->HopNum;k++)
60603 + rdb_remote_link_router_id_get(pOpenRsvpLsp->Path[k].IpAddr,
60604 + &merge_node_router_id);
60605 + if((merge_node_router_id != 0)&&
60606 + (merge_node_router_id != protected_node_router_id))
60608 + frr_sm_call.frr_key.merge_node = merge_node_router_id;
60609 + frr_sm_call.MergeNode = pOpenRsvpLsp->Path[k].IpAddr;
60610 + break;
60613 + if(frr_sm_call.frr_key.merge_node == 0)
60615 + merge_node_router_id =
60616 + frr_sm_call.frr_key.merge_node =
60617 + pOpenRsvpLsp->Path[1].IpAddr;
60618 + frr_sm_call.MergeNode = pOpenRsvpLsp->Path[1].IpAddr;
60620 + for(;k < pOpenRsvpLsp->HopNum;k++)
60622 + rdb_remote_link_router_id_get(pOpenRsvpLsp->Path[k].IpAddr,
60623 + &after_merge_node_router_id);
60624 + if((after_merge_node_router_id != 0)&&
60625 + (after_merge_node_router_id != merge_node_router_id))
60627 + frr_sm_call.frr_key.prohibited_penultimate_node = after_merge_node_router_id;
60628 + break;
60632 + zlog_info("\ncalling FRR SM with key %x %x %x %x",
60633 + frr_sm_call.frr_key.protected_node,
60634 + frr_sm_call.frr_key.OutIfIndex,
60635 + frr_sm_call.frr_key.merge_node,
60636 + frr_sm_call.frr_key.prohibited_penultimate_node);
60638 + frr_sm_call.PsbKey.Session.Dest = pOpenRsvpLsp->Egress;
60639 + frr_sm_call.PsbKey.Session.TunnelId = pOpenRsvpLsp->TunnelId;
60640 + frr_sm_call.PsbKey.Session.ExtTunelId = pOpenRsvpLsp->src_ip;
60641 + frr_sm_call.PsbKey.SenderTemplate.LspId = pOpenRsvpLsp->LspId;
60642 +#ifdef FRR_SM_DEFINED
60643 + if((pCall = fast_reroute_sm_sync_invoke(&frr_sm_call,BYPASS_SETUP_REQ_EVENT)) != NULL)
60645 + zlog_info("\nOK...");
60646 + sm_call(pCall);
60648 + else
60650 + zlog_err("\ncannot invoke FRR SM %s %d",__FILE__,__LINE__);
60652 +#endif
60654 + XFREE(MTYPE_TE,pTunnel->pOpenLspParams);
60655 + pTunnel->pOpenLspParams = NULL;
60656 + zlog_info("leaving CreateAndInvokeRsvpLsp");
60657 + return E_OK;
60660 +uns32 RsvpTunnelTearDown(RSVP_TUNNEL_PROPERTIES *pTunnel,IPV4_ADDR dest,IPV4_ADDR source)
60662 + RSVP_LSP_PROPERTIES *pRsvpLsp = pTunnel->properties;
60663 + TE_API_MSG TeApi;
60664 + PSB_KEY PsbKey;
60666 + zlog_info("entering RsvpTunnelTearDown");
60668 + TeApi.NotificationType = PATH_TEAR_CMD;
60669 + TeApi.u.IngressApi.Egress = dest;
60670 + TeApi.u.IngressApi.TunnelId = pTunnel->TunnelId;
60671 + TeApi.u.IngressApi.src_ip = source;
60673 + memset(&PsbKey,0,sizeof(PSB_KEY));
60675 + PsbKey.Session.Dest = dest;
60676 + PsbKey.Session.TunnelId = pTunnel->TunnelId;
60677 + PsbKey.Session.ExtTunelId = source;
60679 + while(pRsvpLsp != NULL)
60681 + TeApi.u.IngressApi.LspId = pRsvpLsp->LspId;
60682 + te_send_msg(&TeApi,sizeof(TeApi));
60683 +#if DATA_PLANE
60685 + char key[23];
60686 + USER_LSP *pUserLsp;
60687 + IPV4_ADDR next_hop = 0;
60688 + if((pRsvpLsp->tunneled == FALSE)&&(pRsvpLsp->forw_info.path.HopCount != 0))
60690 + next_hop = pRsvpLsp->forw_info.path.pErHopsList[0];
60692 + sprintf(key,"%x%d%x%d",dest,pTunnel->TunnelId,source,pRsvpLsp->LspId);
60693 + mplsTeOutLabel(&pRsvpLsp->Label,1,key,next_hop,0);
60694 + if((pUserLsp = UserLspGet(pTunnel->UserLspName)) != NULL)
60696 + if(pUserLsp->params.PolicyName[0] != '\0')
60698 + mplsTePolicy(pUserLsp->params.PolicyName,key,0);
60702 +#endif
60703 + PsbKey.SenderTemplate.LspId = pRsvpLsp->LspId;
60704 +#ifdef FRR_SM_DEFINED
60705 + FrrIngressRelease(&PsbKey);
60706 +#endif
60707 + pRsvpLsp = pRsvpLsp->next;
60710 + PsbKey.SenderTemplate.LspId = 0;
60711 + StopAdaptivityTimer(pTunnel);
60712 + StopLspSetupTimer(pTunnel);
60713 + StopLspSetupRetryTimer(pTunnel);
60714 + StopCspfRetryTimer(pTunnel);
60715 + if(pTunnel->pCrArgs != NULL)
60717 + if((((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->tunneled == FALSE)&&
60718 + (((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->data.path.ErHopNumber != 0))
60720 + XFREE(MTYPE_TE,((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->data.path.pErHop);
60722 + if(((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->AvoidHopNumber != 0)
60724 + XFREE(MTYPE_TE,((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->AvoidHopsArray);
60726 + if(((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->ExcludeHopNumber != 0)
60728 + XFREE(MTYPE_TE,((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->ExcludeHopsArray);
60730 + if(((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->LinkBwNumber)
60732 + XFREE(MTYPE_TE,((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->pLinkBw);
60734 + XFREE(MTYPE_TE,pTunnel->pCrArgs);
60736 + if(pTunnel->pOpenLspParams != NULL)
60738 + UnregisterClient((int)pTunnel->sm_handle,
60739 + ((INGRESS_API *)(pTunnel->pOpenLspParams))->TunnelId);
60740 + XFREE(MTYPE_TE,pTunnel->pOpenLspParams);
60743 + if(DeleteTunnel(&PsbKey,SEPARATE_NON_ADAPTIVE) != E_OK)
60745 + zlog_err("\ncannot delete tunnel %s %d",__FILE__,__LINE__);
60746 + return E_ERR;
60748 + zlog_info("\nTunnel %x deleted",PsbKey.Session.TunnelId);
60749 + zlog_info("leaving RsvpTunnelTearDown");
60750 + return E_OK;
60753 +void RemoveRsvpLsp(RSVP_TUNNEL_PROPERTIES *pTunnel,uns16 LspId,IPV4_ADDR dest,IPV4_ADDR source)
60755 + RSVP_LSP_PROPERTIES *pRsvpLsp = pTunnel->properties,*pRsvpLspNext,*pRsvpLspPrev = NULL;
60756 + TE_API_MSG TeApi;
60757 + PSB_KEY PsbKey;
60759 + zlog_info("entering RemoveRsvpLsp");
60761 + memset(&PsbKey,0,sizeof(PSB_KEY));
60762 + PsbKey.Session.Dest = dest;
60763 + PsbKey.Session.TunnelId = pTunnel->TunnelId;
60764 + PsbKey.Session.ExtTunelId = source;
60766 + while(pRsvpLsp != NULL)
60768 + /* tear down all that in the range > Allocated */
60769 + if(pRsvpLsp->LspId == LspId)
60771 + /* tear this lsp down */
60772 + TeApi.NotificationType = PATH_TEAR_CMD;
60773 + TeApi.u.IngressApi.Egress = dest;
60774 + TeApi.u.IngressApi.TunnelId = pTunnel->TunnelId;
60775 + TeApi.u.IngressApi.src_ip = source;
60776 + TeApi.u.IngressApi.LspId = pRsvpLsp->LspId;
60777 + /* zlog_info("\nsending tear down request to %x for Dest %x Tunnel %d Source %x LSP %x",
60778 + pRsvpLsp->card,
60779 + dest,
60780 + pTunnel->TunnelId,
60781 + source,
60782 + pRsvpLsp->LspId);*/
60783 + te_send_msg(&TeApi,sizeof(TeApi));
60784 +#if DATA_PLANE
60786 + char key[23];
60787 + USER_LSP *pUserLsp;
60788 + IPV4_ADDR next_hop = 0;
60789 + if((pRsvpLsp->tunneled == FALSE)&&(pRsvpLsp->forw_info.path.HopCount != 0))
60791 + next_hop = pRsvpLsp->forw_info.path.pErHopsList[0];
60793 + sprintf(key,"%x%d%x%d",dest,pTunnel->TunnelId,source,pRsvpLsp->LspId);
60794 + mplsTeOutLabel(&pRsvpLsp->Label,1,key,next_hop,0);
60795 + if((pUserLsp = UserLspGet(pTunnel->UserLspName)) != NULL)
60797 + if(pUserLsp->params.PolicyName[0] != '\0')
60799 + mplsTePolicy(pUserLsp->params.PolicyName,key,0);
60803 +#endif
60804 + PsbKey.SenderTemplate.LspId = pRsvpLsp->LspId;
60805 +#ifdef FRR_SM_DEFINED
60806 + FrrIngressRelease(&PsbKey);
60807 +#endif
60808 + if(pTunnel->LspId == LspId)
60810 + pTunnel->LspId = 0;
60812 + pRsvpLspNext = pRsvpLsp->next;
60813 + if(pRsvpLsp->forw_info.path.pErHopsList != NULL)
60815 + XFREE(MTYPE_TE,pRsvpLsp->forw_info.path.pErHopsList);
60817 + if(pTunnel->properties == pRsvpLsp)
60819 + pTunnel->properties = pTunnel->properties->next;
60821 + else
60823 + pRsvpLspPrev->next = pRsvpLsp->next;
60825 + XFREE(MTYPE_TE,pRsvpLsp);
60826 + pRsvpLsp = pRsvpLspNext;
60828 + else
60830 + pRsvpLspPrev = pRsvpLsp;
60831 + pRsvpLsp = pRsvpLsp->next;
60834 + zlog_info("leaving RemoveRsvpLsp");
60837 +RSVP_LSP_PROPERTIES *FindRsvpLspByLspId(RSVP_TUNNEL_PROPERTIES *pTunnel,uns16 LspId)
60839 + RSVP_LSP_PROPERTIES *pRsvpLsp = pTunnel->properties;
60840 + while(pRsvpLsp != NULL)
60842 + if(pRsvpLsp->LspId == LspId)
60843 + return pRsvpLsp;
60844 + pRsvpLsp = pRsvpLsp->next;
60846 + return pRsvpLsp;
60849 +void FindClosestRsvpLsp(RSVP_TUNNEL_PROPERTIES *pTunnel,
60850 + SETUP_COMPLETE *setup_complete,
60851 + float *BW,
60852 + uns16 *LspId)
60854 + RSVP_LSP_PROPERTIES *pRsvpLsp;
60855 + int i;
60856 + float Delta;
60857 + RSVP_LSP_PROPERTIES *pSelectedRsvpLsp = NULL;
60858 + BOOL GreaterThanRequired;
60860 + zlog_info("entering FindClosestRsvpLsp");
60862 + if(pTunnel->RequiredBW < setup_complete->BW)
60864 + Delta = setup_complete->BW - pTunnel->RequiredBW;
60865 + GreaterThanRequired = TRUE;
60867 + else
60869 + Delta = pTunnel->RequiredBW - setup_complete->BW;
60870 + GreaterThanRequired = FALSE;
60872 + for(i = 0;i < setup_complete->NumberOfItems;i++)
60874 + pRsvpLsp = FindRsvpLspByLspId(pTunnel,setup_complete->pLspLabel[i].LspId);
60875 + if(pRsvpLsp == NULL)
60877 + continue;
60879 + pRsvpLsp->Label = setup_complete->pLspLabel[i].Label;
60880 + if(GreaterThanRequired == TRUE)
60882 + if((pRsvpLsp->RequestedBW > pTunnel->RequiredBW)||
60883 + ((pRsvpLsp->RequestedBW == pTunnel->RequiredBW)&&(pSelectedRsvpLsp == NULL)))
60885 + if((pRsvpLsp->RequestedBW - pTunnel->RequiredBW) <= Delta)
60887 + Delta = pRsvpLsp->RequestedBW - pTunnel->RequiredBW;
60888 + pSelectedRsvpLsp = pRsvpLsp;
60891 + else if(pRsvpLsp->RequestedBW == pTunnel->RequiredBW)
60893 + if(pSelectedRsvpLsp->LspId != 0xFFFF)
60895 + if(pSelectedRsvpLsp->LspId < pRsvpLsp->LspId)
60897 + Delta = 0;
60898 + pSelectedRsvpLsp = pRsvpLsp;
60901 + else
60903 + if(pSelectedRsvpLsp->LspId > pRsvpLsp->LspId)
60905 + Delta = 0;
60906 + pSelectedRsvpLsp = pRsvpLsp;
60911 + else
60913 + if((pTunnel->RequiredBW > pRsvpLsp->RequestedBW)||
60914 + ((pTunnel->RequiredBW == pRsvpLsp->RequestedBW)&&(pSelectedRsvpLsp == NULL)))
60916 + if((pTunnel->RequiredBW - pRsvpLsp->RequestedBW) <= Delta)
60918 + Delta = pTunnel->RequiredBW - pRsvpLsp->RequestedBW;
60919 + pSelectedRsvpLsp = pRsvpLsp;
60922 + else if(pRsvpLsp->RequestedBW == pTunnel->RequiredBW)
60924 + if(pSelectedRsvpLsp->LspId != 0xFFFF)
60926 + if(pSelectedRsvpLsp->LspId < pRsvpLsp->LspId)
60928 + Delta = 0;
60929 + pSelectedRsvpLsp = pRsvpLsp;
60932 + else
60934 + if(pSelectedRsvpLsp->LspId > pRsvpLsp->LspId)
60936 + Delta = 0;
60937 + pSelectedRsvpLsp = pRsvpLsp;
60943 + if(pSelectedRsvpLsp != NULL)
60945 + *BW = pSelectedRsvpLsp->RequestedBW;
60946 + *LspId = pSelectedRsvpLsp->LspId;
60948 + else
60950 + *BW = *LspId = 0;
60952 + zlog_info("leaving FindClosestRsvpLsp");
60955 +SM_CALL_T *DetermineWorkingLspAndTearUnneeded(RSVP_TUNNEL_PROPERTIES *pTunnel,
60956 + float BW,
60957 + uns16 LspId,
60958 + IPV4_ADDR dest,
60959 + IPV4_ADDR source,
60960 + SM_T *pSm)
60962 + RSVP_LSP_PROPERTIES *pRsvpLsp = pTunnel->properties,*pRsvpLspNext,*pRsvpLspPrev = NULL,*pWorkingRsvpLsp = NULL;
60963 + TE_API_MSG TeApi;
60964 + LSP_PATH_SHARED_PARAMS *pParams = NULL;
60965 + PSB_KEY PsbKey;
60966 + SM_CALL_T *pCall = NULL;
60968 + zlog_info("entering DetermineWorkingLspAndTearUnneeded");
60970 + if(BW == pTunnel->RequiredBW) /* modification complete */
60972 + memset(&PsbKey,0,sizeof(PSB_KEY));
60973 + PsbKey.Session.Dest = dest;
60974 + PsbKey.Session.TunnelId = pTunnel->TunnelId;
60975 + PsbKey.Session.ExtTunelId = source;
60977 + while(pRsvpLsp != NULL)
60979 + if(pRsvpLsp->LspId == LspId)
60981 + pWorkingRsvpLsp = pRsvpLsp;
60983 + if((pRsvpLsp->LspId != LspId)&&
60984 + (!((pRsvpLsp->LspId > LspId)&&(pRsvpLsp->RequestedBW == pTunnel->RequiredBW))))
60986 + TeApi.NotificationType = PATH_TEAR_CMD;
60987 + TeApi.u.IngressApi.Egress = dest;
60988 + TeApi.u.IngressApi.TunnelId = pTunnel->TunnelId;
60989 + TeApi.u.IngressApi.src_ip = source;
60990 + TeApi.u.IngressApi.LspId = pRsvpLsp->LspId;
60992 + zlog_info("\nsending tear down request1 for LSP %x tnl %x dest %x src %x bw %x",
60993 + pRsvpLsp->LspId,
60994 + pTunnel->TunnelId,
60995 + dest,
60996 + source,
60997 + pRsvpLsp->RequestedBW);
60999 + te_send_msg(&TeApi,sizeof(TeApi));
61000 +#if DATA_PLANE
61002 + char key[23];
61003 + USER_LSP *pUserLsp;
61004 + IPV4_ADDR next_hop = 0;
61005 + if((pRsvpLsp->tunneled == FALSE)&&(pRsvpLsp->forw_info.path.HopCount != 0))
61007 + next_hop = pRsvpLsp->forw_info.path.pErHopsList[0];
61009 + sprintf(key,"%x%d%x%d",dest,pTunnel->TunnelId,source,pRsvpLsp->LspId);
61010 + zlog_info("delete label %x next hop %x key %s\n",pRsvpLsp->Label,next_hop,key);
61011 + mplsTeOutLabel(&pRsvpLsp->Label,1,key,next_hop,0);
61012 + if((pUserLsp = UserLspGet(pTunnel->UserLspName)) != NULL)
61014 + if(pUserLsp->params.PolicyName[0] != '\0')
61016 + mplsTePolicy(pUserLsp->params.PolicyName,key,0);
61020 +#endif
61021 + PsbKey.SenderTemplate.LspId = pRsvpLsp->LspId;
61022 +#ifdef FRR_SM_DEFINED
61023 + FrrIngressRelease(&PsbKey);
61024 +#endif
61026 + pRsvpLspNext = pRsvpLsp->next;
61028 + if(pTunnel->properties == pRsvpLsp)
61030 + pTunnel->properties = pTunnel->properties->next;
61032 + else
61034 + pRsvpLspPrev->next = pRsvpLsp->next;
61037 + if((pRsvpLsp->tunneled == FALSE)&&
61038 + (pRsvpLsp->forw_info.path.pErHopsList != NULL))
61040 + XFREE(MTYPE_TE,pRsvpLsp->forw_info.path.pErHopsList);
61042 + XFREE(MTYPE_TE,pRsvpLsp);
61044 + pRsvpLsp = pRsvpLspNext;
61046 + else
61048 + pRsvpLspPrev = pRsvpLsp;
61049 + pRsvpLsp = pRsvpLsp->next;
61052 + if(pTunnel->LspId != LspId)
61054 + pTunnel->LspId = LspId;
61055 + pTunnel->AllocatedBW = BW;
61056 + memset(&PsbKey,0,sizeof(PSB_KEY));
61057 + PsbKey.Session.Dest = dest;
61058 + PsbKey.Session.TunnelId = pTunnel->TunnelId;
61059 + PsbKey.Session.ExtTunelId = source;
61061 + if(pWorkingRsvpLsp != NULL)
61063 + IngressLabelMappingReceived(pWorkingRsvpLsp->Label,pWorkingRsvpLsp->oIfIndex,&PsbKey);
61065 + else
61067 + zlog_err("\nBUG: pWorkingRsvpLsp is NULL %s %d",__FILE__,__LINE__);
61071 + else if(BW > pTunnel->RequiredBW)
61073 + if(pTunnel->AllocatedBW < pTunnel->RequiredBW) /* Allocated < RequiredBW < BW */
61075 + memset(&PsbKey,0,sizeof(PSB_KEY));
61076 + PsbKey.Session.Dest = dest;
61077 + PsbKey.Session.TunnelId = pTunnel->TunnelId;
61078 + PsbKey.Session.ExtTunelId = source;
61080 + while(pRsvpLsp != NULL)
61082 + if(pRsvpLsp->LspId == LspId)
61084 + pWorkingRsvpLsp = pRsvpLsp;
61086 + /* tear down all that in the range Allocated < x < Required and > BW */
61087 + /* In another words, only Required < x < BW remains */
61088 + if((pRsvpLsp->LspId != LspId)&&
61089 + ((pRsvpLsp->RequestedBW < pTunnel->RequiredBW)||(pRsvpLsp->RequestedBW > BW)))
61091 + TeApi.NotificationType = PATH_TEAR_CMD;
61092 + TeApi.u.IngressApi.Egress = dest;
61093 + TeApi.u.IngressApi.TunnelId = pTunnel->TunnelId;
61094 + TeApi.u.IngressApi.src_ip = source;
61095 + TeApi.u.IngressApi.LspId = pRsvpLsp->LspId;
61097 + zlog_info("\nsending tear down request2 for LSP %x tnl %x dest %x src %x bw %x",
61098 + pRsvpLsp->LspId,
61099 + pTunnel->TunnelId,
61100 + dest,
61101 + source,
61102 + pRsvpLsp->RequestedBW);
61104 + te_send_msg(&TeApi,sizeof(TeApi));
61105 +#if DATA_PLANE
61107 + char key[23];
61108 + USER_LSP *pUserLsp;
61109 + IPV4_ADDR next_hop = 0;
61110 + if((pRsvpLsp->tunneled == FALSE)&&(pRsvpLsp->forw_info.path.HopCount != 0))
61112 + next_hop = pRsvpLsp->forw_info.path.pErHopsList[0];
61114 + sprintf(key,"%x%d%x%d",dest,pTunnel->TunnelId,source,pRsvpLsp->LspId);
61115 + zlog_info("delete label %x next hop %x key %s\n",pRsvpLsp->Label,next_hop,key);
61116 + mplsTeOutLabel(&pRsvpLsp->Label,1,key,next_hop,0);
61117 + if((pUserLsp = UserLspGet(pTunnel->UserLspName)) != NULL)
61119 + if(pUserLsp->params.PolicyName[0] != '\0')
61121 + mplsTePolicy(pUserLsp->params.PolicyName,key,0);
61125 +#endif
61127 + PsbKey.SenderTemplate.LspId = pRsvpLsp->LspId;
61128 +#ifdef FRR_SM_DEFINED
61129 + FrrIngressRelease(&PsbKey);
61130 +#endif
61131 + pRsvpLspNext = pRsvpLsp->next;
61132 + if(pTunnel->properties == pRsvpLsp)
61133 + pTunnel->properties = pTunnel->properties->next;
61134 + else
61135 + pRsvpLspPrev->next = pRsvpLsp->next;
61137 + if((pRsvpLsp->tunneled == FALSE)&&
61138 + (pRsvpLsp->forw_info.path.pErHopsList != NULL))
61140 + XFREE(MTYPE_TE,pRsvpLsp->forw_info.path.pErHopsList);
61142 + XFREE(MTYPE_TE,pRsvpLsp);
61144 + pRsvpLsp = pRsvpLspNext;
61146 + else
61148 + pRsvpLspPrev = pRsvpLsp;
61149 + pRsvpLsp = pRsvpLsp->next;
61152 + if(pTunnel->LspId != LspId)
61154 + pTunnel->LspId = LspId;
61155 + pTunnel->AllocatedBW = BW;
61156 + memset(&PsbKey,0,sizeof(PSB_KEY));
61157 + PsbKey.Session.Dest = dest;
61158 + PsbKey.Session.TunnelId = pTunnel->TunnelId;
61159 + PsbKey.Session.ExtTunelId = source;
61160 + if(pWorkingRsvpLsp != NULL)
61162 + IngressLabelMappingReceived(pWorkingRsvpLsp->Label,pWorkingRsvpLsp->oIfIndex,&PsbKey);
61164 + else
61166 + zlog_err("\nBUG: pWorkingRsvpLsp is NULL %s %d",__FILE__,__LINE__);
61170 + else /* Required <= Allocated < BW */
61172 + RemoveRsvpLsp(pTunnel,LspId,dest,source);
61175 + else
61177 + if(BW > pTunnel->AllocatedBW) /* AllocatedBW < BW < RequiredBW */
61179 + memset(&PsbKey,0,sizeof(PSB_KEY));
61180 + PsbKey.Session.Dest = dest;
61181 + PsbKey.Session.TunnelId = pTunnel->TunnelId;
61182 + PsbKey.Session.ExtTunelId = source;
61184 + while(pRsvpLsp != NULL)
61186 + if(pRsvpLsp->LspId == LspId)
61188 + pWorkingRsvpLsp = pRsvpLsp;
61190 + /* tear down all that < BW */
61191 + if((pRsvpLsp->LspId != LspId)&&
61192 + (pRsvpLsp->RequestedBW < BW))
61194 + TeApi.NotificationType = PATH_TEAR_CMD;
61195 + TeApi.u.IngressApi.Egress = dest;
61196 + TeApi.u.IngressApi.TunnelId = pTunnel->TunnelId;
61197 + TeApi.u.IngressApi.src_ip = source;
61198 + TeApi.u.IngressApi.LspId = pRsvpLsp->LspId;
61200 + zlog_info("\nsending tear down request3 for LSP %x tnl %x dest %x src %x bw %x",
61201 + pRsvpLsp->LspId,
61202 + pTunnel->TunnelId,
61203 + dest,
61204 + source,
61205 + pRsvpLsp->RequestedBW);
61207 + te_send_msg(&TeApi,sizeof(TeApi));
61208 +#if DATA_PLANE
61210 + char key[23];
61211 + USER_LSP *pUserLsp;
61212 + IPV4_ADDR next_hop = 0;
61213 + if((pRsvpLsp->tunneled == FALSE)&&(pRsvpLsp->forw_info.path.HopCount != 0))
61215 + next_hop = pRsvpLsp->forw_info.path.pErHopsList[0];
61217 + sprintf(key,"%x%d%x%d",dest,pTunnel->TunnelId,source,pRsvpLsp->LspId);
61218 + zlog_info("delete label %x next hop %x key %s\n",pRsvpLsp->Label,next_hop,key);
61219 + mplsTeOutLabel(&pRsvpLsp->Label,1,key,next_hop,0);
61220 + if((pUserLsp = UserLspGet(pTunnel->UserLspName)) != NULL)
61222 + if(pUserLsp->params.PolicyName[0] != '\0')
61224 + mplsTePolicy(pUserLsp->params.PolicyName,key,0);
61228 +#endif
61229 + PsbKey.SenderTemplate.LspId = pRsvpLsp->LspId;
61230 +#ifdef FRR_SM_DEFINED
61231 + FrrIngressRelease(&PsbKey);
61232 +#endif
61233 + pRsvpLspNext = pRsvpLsp->next;
61234 + if(pTunnel->properties == pRsvpLsp)
61235 + pTunnel->properties = pTunnel->properties->next;
61236 + else
61237 + pRsvpLspPrev->next = pRsvpLsp->next;
61239 + if((pRsvpLsp->tunneled == FALSE)&&
61240 + (pRsvpLsp->forw_info.path.pErHopsList != NULL))
61242 + XFREE(MTYPE_TE,pRsvpLsp->forw_info.path.pErHopsList);
61244 + XFREE(MTYPE_TE,pRsvpLsp);
61246 + pRsvpLsp = pRsvpLspNext;
61248 + else
61250 + pRsvpLspPrev = pRsvpLsp;
61251 + pRsvpLsp = pRsvpLsp->next;
61254 + if(pTunnel->LspId != LspId)
61256 + pTunnel->LspId = LspId;
61257 + pTunnel->AllocatedBW = BW;
61258 + memset(&PsbKey,0,sizeof(PSB_KEY));
61259 + PsbKey.Session.Dest = dest;
61260 + PsbKey.Session.TunnelId = pTunnel->TunnelId;
61261 + PsbKey.Session.ExtTunelId = source;
61262 + if(pWorkingRsvpLsp != NULL)
61264 + IngressLabelMappingReceived(pWorkingRsvpLsp->Label,pWorkingRsvpLsp->oIfIndex,&PsbKey);
61266 + else
61268 + zlog_err("\nBUG: pWorkingRsvpLsp is NULL %s %d",__FILE__,__LINE__);
61272 + else /* BW <= Allocated < Required */
61274 + RemoveRsvpLsp(pTunnel,LspId,dest,source);
61277 + if(pTunnel->properties != NULL)
61279 + if(pTunnel->properties->next == NULL)
61281 + if(pTunnel->properties->LspId == pTunnel->LspId)
61283 + USER_LSP *pUserLsp;
61284 + pTunnel->ReRoute = FALSE;
61285 + if((pUserLsp = UserLspGet(pTunnel->UserLspName)) != NULL)
61286 + {
61287 + RSVP_TUNNEL_PROPERTIES *pTunnel1 = pUserLsp->pUserLspTunnels;
61288 + StopLspSetupTimer(pTunnel);
61289 + if((pUserLsp->pUserLspTunnels)&&(pUserLsp->pUserLspTunnels->TunnelId == pTunnel->TunnelId))
61291 + StopLspSetupRetryTimer(pTunnel);
61294 + if(pTunnel->AdjustmentRequired == TRUE)
61296 + zlog_info("Adjustment required for tunnel %x",pTunnel->TunnelId);
61297 + pTunnel->AdjustmentRequired = FALSE;
61298 + while(pTunnel1 != NULL)
61300 + if(pTunnel1->TunnelId == pTunnel->TunnelId)
61301 + break;
61302 + pTunnel1 = pTunnel1->next_user_lsp_tunnel;
61305 + else if(pTunnel1)
61307 + pTunnel1 = pTunnel1->next_user_lsp_tunnel;
61309 + if(pTunnel1 != NULL)
61311 + STATIC_PATH *pStaticPath;
61313 + if(rdb_get_static_path(pTunnel->StaticPathName,
61314 + &pStaticPath) != E_OK)
61316 + pStaticPath = NULL;
61318 + pCall = ModifySecondary(pTunnel1,
61319 + pSm,
61320 + pStaticPath,
61321 + pUserLsp);
61323 + pParams = PathParamsGet(pUserLsp,
61324 + pTunnel->StaticPathName,
61325 + ((!strcmp(pUserLsp->params.Primary,pTunnel->StaticPathName))&&(pUserLsp->pUserLspTunnels->TunnelId == pTunnel->TunnelId)));
61326 + StartAdaptivityTimer(pParams->optimize_timer,pTunnel);
61329 + else
61331 + zlog_err("\none RSVP LSP remains and it is not a working LSP!!! %s %d",__FILE__,__LINE__);
61335 + else
61337 + zlog_err("\npTunnel->properties is NULL %s %d",__FILE__,__LINE__);
61339 + zlog_info("leaving DetermineWorkingLspAndTearUnneeded");
61340 + return pCall;
61343 +RSVP_LSP_PROPERTIES *GetRsvpLspMaxBW(RSVP_TUNNEL_PROPERTIES *pTunnel,uns16 LspId,float MaxBw)
61345 + RSVP_LSP_PROPERTIES *pRsvpLsp = pTunnel->properties,*pSelectedRsvpLsp = NULL;
61346 + float MaxRsvpLspBW = 0;
61347 + while(pRsvpLsp != NULL)
61349 + if((pRsvpLsp->RequestedBW <= MaxBw)&&
61350 + (pRsvpLsp->LspId != LspId)&&
61351 + (pRsvpLsp->RequestedBW > MaxRsvpLspBW))
61352 + pSelectedRsvpLsp = pRsvpLsp;
61353 + pRsvpLsp = pRsvpLsp->next;
61355 + return pSelectedRsvpLsp;
61358 +BOOL IsPathEqual(PATH *pPath,IPV4_ADDR *IpAddrList)
61360 + ER_HOP_L_LIST *pErHopLList = pPath->u.er_hops_l_list;
61361 + int i = 0;
61363 + while(pErHopLList != NULL)
61365 + if(pErHopLList->er_hop->local_ip != IpAddrList[i])
61366 + return FALSE;
61367 + pErHopLList = pErHopLList->next;
61368 + i++;
61370 + return TRUE;
61373 +PATH *FindRsvpLspPath(PATH_L_LIST *pPaths,RSVP_LSP_PROPERTIES *pRsvpLsp)
61375 + while(pPaths != NULL)
61377 + PATH *pPath = pPaths->pPath;
61379 + if((pPath->PathProperties.PathHopCount + 1) == pRsvpLsp->forw_info.path.HopCount)
61381 + if(IsPathEqual(pPath,pRsvpLsp->forw_info.path.pErHopsList) == TRUE)
61382 + return pPath;
61384 + pPaths = pPaths->next;
61386 + return NULL;
61389 +RSVP_LSP_PROPERTIES *CurrentPathHasAvBw(RSVP_TUNNEL_PROPERTIES *pTunnel,float BW)
61391 + RSVP_LSP_PROPERTIES *pRsvpLsp;
61392 + PATH *pPath;
61393 + float Delta;
61395 + zlog_info("entering CurrentPathHasAvBw");
61397 + if((pRsvpLsp = GetWorkingRsvpLsp(pTunnel)) != NULL)
61399 + if((pPath = GetLspPath(pRsvpLsp)) != NULL)
61401 + if(pPath->PathProperties.PathMaxLspBW >= BW)
61403 + if(pRsvpLsp->RequestedBW < BW)
61404 + Delta = BW - pRsvpLsp->RequestedBW;
61405 + else
61406 + Delta = pRsvpLsp->RequestedBW - BW;
61408 + if(pPath->PathProperties.PathReservableBW[pRsvpLsp->SetupPriority] >= Delta)
61409 + return pRsvpLsp;
61412 + else
61413 + zlog_info("cannot get working lsp's path %s %d",__FILE__,__LINE__);
61415 + else
61416 + zlog_info("cannot get working lsp %s %d",__FILE__,__LINE__);
61417 + zlog_info("leaving CurrentPathHasAvBw");
61418 + return NULL;
61421 +uns32 AddSecondaryTunnel(USER_LSP *pUserLsp,
61422 + RSVP_TUNNEL_PROPERTIES *pSecondaryTunnel)
61424 + RSVP_TUNNEL_PROPERTIES *pTunnel,*pTunnelPrev = NULL;
61426 + zlog_info("entering AddSecondaryTunnel");
61428 + if((pTunnel = pUserLsp->pUserLspTunnels) == NULL)
61430 + zlog_err("\nFATAL at %s %d - TunnelIdList is empty",__FILE__,__LINE__);
61431 + return E_ERR;
61433 + zlog_info("Primary: %x %s",pTunnel->TunnelId,pTunnel->StaticPathName);
61434 + if(pTunnel->next_user_lsp_tunnel == NULL)
61436 + zlog_info("First secondary tunnel %s %d",__FILE__,__LINE__);
61437 + pTunnel->next_user_lsp_tunnel = pSecondaryTunnel;
61438 + return E_OK;
61440 + pTunnel = pTunnel->next_user_lsp_tunnel;
61441 + while(pTunnel != NULL)
61443 + if(pTunnel->TunnelId == pSecondaryTunnel->TunnelId)
61445 + zlog_info("exists on the lists...");
61446 + zlog_info("leaving AddSecondaryTunnel");
61447 + return E_OK;
61449 + pTunnelPrev = pTunnel;
61450 + pTunnel = pTunnel->next_user_lsp_tunnel;
61452 + pTunnelPrev->next_user_lsp_tunnel = pSecondaryTunnel;
61453 + zlog_info("leaving AddSecondaryTunnel");
61454 + return E_OK;
61457 +void CleanSecodaryPaths(USER_LSP *pUserLsp)
61459 + SECONDARY_PATH_LIST *pSecPathList = pUserLsp->params.SecondaryPaths,*pSecPathListNext;
61460 + while(pSecPathList != NULL)
61462 + if(pSecPathList->SecondaryPathParams != NULL)
61463 + XFREE(MTYPE_TE,pSecPathList->SecondaryPathParams);
61464 + pSecPathListNext = pSecPathList->next;
61465 + XFREE(MTYPE_TE,pSecPathList);
61466 + pSecPathList = pSecPathListNext;
61470 +void CleanUserLsp(USER_LSP *pUserLsp)
61472 +#if 0
61473 + if(pUserLsp->params.FastReroute != NULL)
61474 + XFREE(MTYPE_TE,pUserLsp->params.FastReroute);
61475 +#endif
61476 + if(pUserLsp->params.PrimaryPathParams != NULL)
61477 + XFREE(MTYPE_TE,pUserLsp->params.PrimaryPathParams);
61480 +void CopyUserLsp(USER_LSP *pDestLsp,USER_LSP *pSrcLsp)
61482 + SECONDARY_PATH_LIST *pDestSecondaryPathList,*pSrcSecondaryPathList,*pPrevSecPath;
61484 + zlog_info("entering CopyUserLsp");
61486 + strcpy(pDestLsp->params.LspName,pSrcLsp->params.LspName);
61488 + if((pDestLsp->params.PrimaryPathParams)&&
61489 + (((pSrcLsp->params.PrimaryPathParams)&&(pSrcLsp->params.PrimaryPathParams->disable))||
61490 + (!pSrcLsp->params.PrimaryPathParams)))
61492 + zlog_info("removing primary %s %s %d",pDestLsp->params.Primary,__FILE__,__LINE__);
61493 + XFREE(MTYPE_TE,pDestLsp->params.PrimaryPathParams);
61494 + pDestLsp->params.PrimaryPathParams = NULL;
61495 + pDestLsp->params.Primary[0] = '\0';
61496 + if(pSrcLsp->params.PrimaryPathParams)
61498 + XFREE(MTYPE_TE,pSrcLsp->params.PrimaryPathParams);
61499 + pSrcLsp->params.PrimaryPathParams = NULL;
61501 + pSrcLsp->params.Primary[0] = '\0';
61503 + strcpy(pDestLsp->params.Primary,pSrcLsp->params.Primary);
61504 +#if 0
61505 + pDestLsp->params.FastReroute = pSrcLsp->params.FastReroute;
61506 + pSrcLsp->params.FastReroute = NULL;
61507 +#endif
61508 + if(pDestLsp->params.PrimaryPathParams != NULL)
61510 + XFREE(MTYPE_TE,pDestLsp->params.PrimaryPathParams);
61512 + pDestLsp->params.PrimaryPathParams = pSrcLsp->params.PrimaryPathParams;
61513 + pSrcLsp->params.PrimaryPathParams = NULL;
61514 + pDestSecondaryPathList = pDestLsp->params.SecondaryPaths;
61515 + while(pDestSecondaryPathList != NULL)
61517 + pSrcSecondaryPathList = pSrcLsp->params.SecondaryPaths;
61518 + pPrevSecPath = NULL;
61519 + while(pSrcSecondaryPathList != NULL)
61521 + if(strcmp(pDestSecondaryPathList->Secondary,pSrcSecondaryPathList->Secondary) == 0)
61523 + if(pDestSecondaryPathList->SecondaryPathParams != NULL)
61525 + XFREE(MTYPE_TE,pDestSecondaryPathList->SecondaryPathParams);
61527 + pDestSecondaryPathList->SecondaryPathParams = pSrcSecondaryPathList->SecondaryPathParams;
61528 + pSrcSecondaryPathList->SecondaryPathParams = NULL;
61529 + if(pPrevSecPath != NULL)
61531 + pPrevSecPath->next = pSrcSecondaryPathList->next;
61533 + else
61535 + pSrcLsp->params.SecondaryPaths = pSrcLsp->params.SecondaryPaths->next;
61537 + XFREE(MTYPE_TE,pSrcSecondaryPathList);
61538 + break;
61540 + pPrevSecPath = pSrcSecondaryPathList;
61541 + pSrcSecondaryPathList = pSrcSecondaryPathList->next;
61543 + if(pDestSecondaryPathList->next == NULL)
61545 + pDestSecondaryPathList->next = pSrcLsp->params.SecondaryPaths;
61546 + break;
61548 + pDestSecondaryPathList = pDestSecondaryPathList->next;
61550 + if(pDestLsp->params.SecondaryPaths == NULL)
61552 + pDestLsp->params.SecondaryPaths = pSrcLsp->params.SecondaryPaths;
61554 + if(pDestLsp->params.FastReRoute != pSrcLsp->params.FastReRoute)
61556 + pDestLsp->params.FastReRoute = pSrcLsp->params.FastReRoute;
61558 + if(pDestLsp->params.bw_policy != pSrcLsp->params.bw_policy)
61560 + pDestLsp->params.bw_policy = pSrcLsp->params.bw_policy;
61562 + if(pDestLsp->params.metric != pSrcLsp->params.metric)
61564 + pDestLsp->params.metric = pSrcLsp->params.metric;
61566 + if(pDestLsp->params.no_decrement_ttl != pSrcLsp->params.no_decrement_ttl)
61568 + pDestLsp->params.no_decrement_ttl = pSrcLsp->params.no_decrement_ttl;
61570 + if(pDestLsp->params.retry_timer != pSrcLsp->params.retry_timer)
61572 + pDestLsp->params.retry_timer = pSrcLsp->params.retry_timer;
61574 + if(pDestLsp->params.retry_limit != pSrcLsp->params.retry_limit)
61576 + pDestLsp->params.retry_limit = pSrcLsp->params.retry_limit;
61578 + pDestLsp->params.retry_count = pSrcLsp->params.retry_limit;
61579 + if(memcmp(&pDestLsp->params.lsp_params,&pSrcLsp->params.lsp_params,sizeof(LSP_PATH_SHARED_PARAMS)) != 0)
61581 + pDestLsp->params.lsp_params = pSrcLsp->params.lsp_params;
61583 + zlog_info("leaving CopyUserLsp");
61586 +LSP_PATH_SHARED_PARAMS *PathParamsGet(USER_LSP *pUserLsp,char *PathName,uns8 IsPrimary)
61588 + zlog_info("entering PathParamsGet");
61590 + if((IsPrimary)&&(strcmp(pUserLsp->params.Primary,PathName) == 0))
61592 + if(pUserLsp->params.PrimaryPathParams != NULL)
61594 + return pUserLsp->params.PrimaryPathParams;
61596 + else
61598 + return &pUserLsp->params.lsp_params;
61601 + else if(!IsPrimary)
61603 + SECONDARY_PATH_LIST *pSecondaryPathList = pUserLsp->params.SecondaryPaths;
61604 + while(pSecondaryPathList != NULL)
61606 + if(strcmp(pSecondaryPathList->Secondary,PathName) == 0)
61608 + if(pSecondaryPathList->SecondaryPathParams != NULL)
61610 + return pSecondaryPathList->SecondaryPathParams;
61612 + else
61614 + return &pUserLsp->params.lsp_params;
61617 + pSecondaryPathList = pSecondaryPathList->next;
61620 + zlog_info("leaving PathParamsGet");
61621 + return &pUserLsp->params.lsp_params;
61624 +RSVP_TUNNEL_PROPERTIES *StaticPathIsUsed(USER_LSP *pUserLsp,char *PathName)
61626 + RSVP_TUNNEL_PROPERTIES *pTunnel = pUserLsp->pUserLspTunnels;
61628 + zlog_info("entering StaticPathIsUsed");
61630 + if(pTunnel != NULL)
61632 + pTunnel = pTunnel->next_user_lsp_tunnel;
61634 + while(pTunnel != NULL)
61636 + if(strcmp(pTunnel->StaticPathName,PathName) == 0)
61637 + return pTunnel;
61638 + pTunnel = pTunnel->next_user_lsp_tunnel;
61640 + zlog_info("leaving StaticPathIsUsed");
61641 + return NULL;
61644 +SM_CALL_T *UserPrimaryLspRecovery(RSVP_TUNNEL_PROPERTIES *pTunnel,
61645 + SM_T *pSm,
61646 + RECOVERY_TYPE_E recovery_type,
61647 + IPV4_ADDR exclude_node)
61649 + STATIC_PATH *pStaticPath;
61650 + USER_LSP *pUserLsp;
61651 + SECONDARY_PATH_LIST *pSecondaryPathList;
61652 + INGRESS_API *pOpenLspParams;
61653 + SM_CALL_T *pCall = NULL;
61654 + RSVP_TUNNEL_PROPERTIES *pSavedTunnel = pTunnel;
61655 + LSP_PATH_SHARED_PARAMS *pParams = NULL;
61656 + uns8 Flags = 0;
61657 + ER_HOP *pErHopsList = NULL;
61659 + zlog_info("entering UserPrimaryLspRecovery");
61661 + if((pUserLsp = UserLspGet(pTunnel->UserLspName)) == NULL)
61663 + zlog_err("\nerror: cannot get user lsp %s %d",__FILE__,__LINE__);
61664 + return NULL;
61666 + pTunnel = pTunnel->next_user_lsp_tunnel;
61667 + /* First - try to find secondary LSP (hot-standby), which is UP */
61668 + if(recovery_type == WORKING_LSP_FAILED)
61670 + while(pTunnel != NULL)
61672 + RSVP_LSP_PROPERTIES *pRsvpLsp;
61673 + if((pRsvpLsp = GetWorkingRsvpLsp(pTunnel)) != NULL)
61675 +#if DATA_PLANE
61677 + char key[23];
61678 + sprintf(key,"%x%d%x%d",pUserLsp->params.to,pTunnel->TunnelId,pUserLsp->params.from,pRsvpLsp->LspId);
61679 + if(pUserLsp->params.PolicyName[0] != '\0')
61681 + mplsTePolicy(pUserLsp->params.PolicyName,key,1);
61682 + pUserLsp->BackupTunnelId = pTunnel->TunnelId;
61685 +#endif
61686 + zlog_info("Protection switch to secondary hot-stanby tunnel Dest %x Tunnel %x Source %x %s %s %x",
61687 + pUserLsp->params.to,
61688 + pTunnel->TunnelId,
61689 + pUserLsp->params.from,
61690 + pTunnel->StaticPathName,
61691 + __FILE__,__LINE__);
61692 + strcpy(pUserLsp->CurrentSecondaryPathName,pTunnel->StaticPathName);
61693 + if(StartLspSetupRetryTimer(pUserLsp->params.retry_timer,
61694 + &pUserLsp->params.retry_count,
61695 + pSavedTunnel) != E_OK)
61697 + zlog_err("cannot start lsp setup retry timer %s %d",__FILE__,__LINE__);
61699 + return NULL;
61701 + pTunnel = pTunnel->next_user_lsp_tunnel;
61705 + /* if reached here, there is no hot-stanby tunnels UP. */
61706 + pSecondaryPathList = pUserLsp->params.SecondaryPaths;
61707 + /* if there is secondary path, which was used, spin up the secondary paths to get next secondary path */
61708 + if(pUserLsp->CurrentSecondaryPathName[0] != 0)
61710 + while(pSecondaryPathList != NULL)
61712 + if(strcmp(pSecondaryPathList->Secondary,pUserLsp->CurrentSecondaryPathName) == 0)
61714 + pSecondaryPathList = pSecondaryPathList->next;
61715 + break;
61717 + pSecondaryPathList = pSecondaryPathList->next;
61719 + if(pSecondaryPathList == NULL)
61721 + pSecondaryPathList = pUserLsp->params.SecondaryPaths;
61725 + while(pSecondaryPathList != NULL)
61727 + if(strcmp(pSecondaryPathList->Secondary,pUserLsp->CurrentSecondaryPathName) == 0)
61729 + pSecondaryPathList = NULL;
61730 + break;
61732 + if(StaticPathIsUsed(pUserLsp,pSecondaryPathList->Secondary) == NULL)
61734 + if(rdb_get_static_path(pSecondaryPathList->Secondary,
61735 + &pStaticPath) == E_OK)
61737 + break;
61740 + pSecondaryPathList = pSecondaryPathList->next;
61743 + if(pUserLsp->pUserLspTunnels == NULL)
61745 + zlog_err("\nSW ERROR %s %d",__FILE__,__LINE__);
61746 + return NULL;
61749 + if(pSecondaryPathList != NULL)
61751 + pParams = PathParamsGet(pUserLsp,pSecondaryPathList->Secondary,0);
61752 + Flags |= (pParams->record == TRUE) ? LABEL_RECORDING_DESIRED : 0;
61753 + /* for now the FRR is only boolean. However, in future it may be more complicated */
61754 + Flags |= (pUserLsp->params.FastReRoute == TRUE) ? LOCAL_PROTECTION_DESIRED : 0;
61755 + if(SetErHopList(pStaticPath,&pErHopsList) != E_OK)
61757 + zlog_err("Cannot set ER hops list %s %d",__FILE__,__LINE__);
61758 + return NULL;
61760 + /* reroute primary LSP to the secondary path */
61761 + if((pOpenLspParams = CreateRequest2Signalling(pUserLsp->params.to,
61762 + pUserLsp->pUserLspTunnels->TunnelId,
61763 + pStaticPath->HopCount,
61764 + pErHopsList,
61765 + pParams->BW,
61766 + pParams->setup_priority,
61767 + pParams->hold_priority,
61768 + Flags,
61769 + (~(pParams->affinity_properties & pParams->affinity_mask)) & pParams->affinity_mask,
61770 + 0,
61771 + pParams->affinity_properties & pParams->affinity_mask)) == NULL)
61773 + zlog_err("\nmalloc failed %s %d",__FILE__,__LINE__);
61774 + XFREE(MTYPE_TE,pErHopsList);
61775 + return NULL;
61778 + zlog_info("\nRerouting primary: Dest %x Tunnel %x Source %x New Path %s",
61779 + pOpenLspParams->Egress,
61780 + pOpenLspParams->TunnelId,
61781 + pOpenLspParams->src_ip,
61782 + pSecondaryPathList->Secondary);
61784 + strcpy(pUserLsp->CurrentSecondaryPathName,pSecondaryPathList->Secondary);
61785 + if(StartLspSetupRetryTimer(pUserLsp->params.retry_timer,&pUserLsp->params.retry_count,pSavedTunnel) != E_OK)
61787 + zlog_err("\ncannot start lsp setup retry timer %s %d",__FILE__,__LINE__);
61789 + pParams = PathParamsGet(pUserLsp,pStaticPath->PathName,0);
61790 + if(pUserLsp->params.to != exclude_node)
61791 + pOpenLspParams->ErHops2Exclude[0] = exclude_node;
61792 + pCall = LspRequest(pOpenLspParams,0,NULL,pSm,&pSavedTunnel,TRUE,pParams);
61793 + strcpy(pSavedTunnel->StaticPathName,pSecondaryPathList->Secondary);
61794 + return pCall;
61798 + if(rdb_get_static_path(pSavedTunnel->StaticPathName,
61799 + &pStaticPath) != E_OK)
61801 + pStaticPath = NULL;
61804 + pParams = PathParamsGet(pUserLsp,
61805 + pSavedTunnel->StaticPathName,
61806 + ((!strcmp(pUserLsp->params.Primary,pSavedTunnel->StaticPathName))&&(pUserLsp->pUserLspTunnels->TunnelId == pSavedTunnel->TunnelId)));
61808 + if(StartLspSetupRetryTimer(pUserLsp->params.retry_timer,&pUserLsp->params.retry_count,pSavedTunnel) != E_OK)
61810 + zlog_err("\ncannot start lsp setup retry timer %s %d",__FILE__,__LINE__);
61813 + if((pStaticPath != NULL)&&
61814 + (pStaticPath->HopList != NULL)&&
61815 + (pStaticPath->HopList->Loose == 1))
61817 + /* reroute primary LSP to the secondary path */
61818 + if(SetErHopList(pStaticPath,&pErHopsList) != E_OK)
61820 + zlog_err("Cannot set ER hops list %s %d",__FILE__,__LINE__);
61821 + return NULL;
61824 + else
61826 + pStaticPath = NULL;
61828 + Flags |= (pParams->record == TRUE) ? LABEL_RECORDING_DESIRED : 0;
61829 + /* for now the FRR is only boolean. However, in future it may be more complicated */
61830 + Flags |= (pUserLsp->params.FastReRoute == TRUE) ? LOCAL_PROTECTION_DESIRED : 0;
61831 + if((pOpenLspParams = CreateRequest2Signalling(pUserLsp->params.to,
61832 + pUserLsp->pUserLspTunnels->TunnelId,
61833 + (pStaticPath == NULL) ? 0 : pStaticPath->HopCount,
61834 + pErHopsList,
61835 + pParams->BW,
61836 + pParams->setup_priority,
61837 + pParams->hold_priority,
61838 + Flags,
61839 + (~(pParams->affinity_properties & pParams->affinity_mask)) & pParams->affinity_mask,
61840 + 0,
61841 + pParams->affinity_properties & pParams->affinity_mask)) == NULL)
61843 + zlog_err("malloc failed %s %d",__FILE__,__LINE__);
61844 + return NULL;
61847 + zlog_info("Creation secondary - %x %x %s %d",pOpenLspParams->Egress,pOpenLspParams->src_ip,__FILE__,__LINE__);
61848 + if(pUserLsp->params.to != exclude_node)
61849 + pOpenLspParams->ErHops2Exclude[0] = exclude_node;
61850 + return LspRequest(pOpenLspParams,0,NULL,pSm,&pSavedTunnel,TRUE,pParams);
61853 +SM_CALL_T *UserSecondaryLspRecovery(RSVP_TUNNEL_PROPERTIES *pTunnel,SM_T *pSm,IPV4_ADDR exclude_node)
61855 + LSP_PATH_SHARED_PARAMS *pSecondaryPathParams;
61856 + USER_LSP *pUserLsp;
61857 + STATIC_PATH *pStaticPath;
61858 + INGRESS_API *pOpenLspParams;
61859 + uns32 ErHopNumber = 0;
61860 + IPV4_ADDR *pErHops = NULL;
61861 + uns8 Flags = 0;
61862 + ER_HOP *pErHopsList = NULL;
61864 + zlog_info("entering UserSecondaryLspRecovery");
61866 + if((pUserLsp = UserLspGet(pTunnel->UserLspName)) == NULL)
61868 + zlog_err("\nerror: cannot get user lsp %s %d",__FILE__,__LINE__);
61869 + return NULL;
61871 + if(pUserLsp->pUserLspTunnels == NULL)
61873 + zlog_err("\nTunnel ID list empty %s %d",__FILE__,__LINE__);
61874 + return NULL;
61876 + pSecondaryPathParams = PathParamsGet(pUserLsp,pTunnel->StaticPathName,0);
61878 + if(rdb_get_static_path(pTunnel->StaticPathName,
61879 + &pStaticPath) != E_OK)
61881 + Flags |= (pSecondaryPathParams->record == TRUE) ? LABEL_RECORDING_DESIRED : 0;
61882 + /* for now the FRR is only boolean. However, in future it may be more complicated */
61883 + Flags |= (pUserLsp->params.FastReRoute == TRUE) ? LOCAL_PROTECTION_DESIRED : 0;
61885 + /* reroute the secondary LSP inside of the path */
61886 + if((pOpenLspParams = CreateRequest2Signalling(pUserLsp->params.to,
61887 + pTunnel->TunnelId,
61888 + 0,
61889 + NULL,
61890 + pSecondaryPathParams->BW,
61891 + pSecondaryPathParams->setup_priority,
61892 + pSecondaryPathParams->hold_priority,
61893 + Flags,
61894 + (~(pSecondaryPathParams->affinity_properties & pSecondaryPathParams->affinity_mask)) & pSecondaryPathParams->affinity_mask,
61895 + 0,
61896 + pSecondaryPathParams->affinity_properties & pSecondaryPathParams->affinity_mask)) == NULL)
61898 + zlog_err("\nmalloc failed %s %d",__FILE__,__LINE__);
61899 + return NULL;
61902 + if(GetTunnelHops(pUserLsp->pUserLspTunnels,&ErHopNumber,&pErHops) != E_OK)
61904 + zlog_err("\ncannot get ER HOPs to be avoided %s %d",__FILE__,__LINE__);
61905 + ErHopNumber = 0;
61906 + pErHops = NULL;
61908 + if(pUserLsp->params.to != exclude_node)
61909 + pOpenLspParams->ErHops2Exclude[0] = exclude_node;
61910 + return LspRequest(pOpenLspParams,ErHopNumber,pErHops,pSm,&pTunnel,TRUE,pSecondaryPathParams);
61913 + Flags |= (pSecondaryPathParams->record == TRUE) ? LABEL_RECORDING_DESIRED : 0;
61914 + /* for now the FRR is only boolean. However, in future it may be more complicated */
61915 + Flags |= (pUserLsp->params.FastReRoute == TRUE) ? LOCAL_PROTECTION_DESIRED : 0;
61916 + if(pStaticPath != NULL)
61918 + if(SetErHopList(pStaticPath,&pErHopsList) != E_OK)
61920 + zlog_err("Cannot set ER hops list %s %d",__FILE__,__LINE__);
61921 + return NULL;
61924 + /* reroute the secondary LSP inside of the path */
61925 + if((pOpenLspParams = CreateRequest2Signalling(pUserLsp->params.to,
61926 + pTunnel->TunnelId,
61927 + pStaticPath->HopCount,
61928 + pErHopsList,
61929 + pSecondaryPathParams->BW,
61930 + pSecondaryPathParams->setup_priority,
61931 + pSecondaryPathParams->hold_priority,
61932 + Flags,
61933 + (~(pSecondaryPathParams->affinity_properties & pSecondaryPathParams->affinity_mask)) & pSecondaryPathParams->affinity_mask,
61934 + 0,
61935 + pSecondaryPathParams->affinity_properties & pSecondaryPathParams->affinity_mask)) == NULL)
61937 + zlog_err("\nmalloc failed %s %d",__FILE__,__LINE__);
61938 + return NULL;
61940 + if(!((pErHopsList != NULL)&&(pErHopsList[0].Loose == 0)))
61942 + if(GetTunnelHops(pUserLsp->pUserLspTunnels,&ErHopNumber,&pErHops) != E_OK)
61944 + zlog_err("\ncannot get ER HOPs to be avoided %s %d",__FILE__,__LINE__);
61945 + ErHopNumber = 0;
61946 + pErHops = NULL;
61949 + if(pUserLsp->params.to != exclude_node)
61950 + pOpenLspParams->ErHops2Exclude[0] = exclude_node;
61951 + return LspRequest(pOpenLspParams,ErHopNumber,pErHops,pSm,&pTunnel,TRUE,pSecondaryPathParams);
61954 +SM_CALL_T *UserLspFailed(RSVP_TUNNEL_PROPERTIES *pTunnel,SM_T *pSm,IPV4_ADDR exclude_node)
61956 + USER_LSP *pUserLsp;
61957 + RECOVERY_TYPE_E recovery_type = WORKING_LSP_FAILED;
61959 + zlog_info("entering UserLspFailed");
61960 + zlog_info("Exclude Node %x",exclude_node);
61961 + if((pUserLsp = UserLspGet(pTunnel->UserLspName)) == NULL)
61963 + zlog_err("\nerror: cannot get user lsp %s %d",__FILE__,__LINE__);
61964 + return NULL;
61966 + if(pUserLsp->pUserLspTunnels == NULL)
61968 + zlog_err("\nerror: tunnel id list empty %s %d",__FILE__,__LINE__);
61969 + return NULL;
61972 + if(pUserLsp->pUserLspTunnels->TunnelId == pTunnel->TunnelId)
61974 + if(GetWorkingRsvpLsp(pTunnel)!= NULL)
61976 + if(pTunnel->ReRoute == TRUE)
61978 + recovery_type = NEW_LSP_FAILED;
61980 + else
61982 + zlog_info("\nLSP is not rerouted and having working lsp...");
61983 + return NULL;
61986 + else
61988 + if((pTunnel->ReRoute == TRUE)&&
61989 + (pTunnel->properties != NULL))
61991 + zlog_info("\nLSP is not working lsp, reroute lasts...");
61992 + return NULL;
61995 + zlog_info("\nPrimary Tunnel failed Dest %x Tunnel ID %x Source %x recovery type %d",
61996 + pUserLsp->params.to,pUserLsp->pUserLspTunnels->TunnelId,pUserLsp->params.from,recovery_type);
61997 + return UserPrimaryLspRecovery(pTunnel,pSm,recovery_type,exclude_node);
62000 + else
62002 + if(GetWorkingRsvpLsp(pTunnel)== NULL)
62004 + if((pTunnel->ReRoute == TRUE)&&
62005 + (pTunnel->properties != NULL))
62007 + return NULL;
62009 + else
62011 + zlog_info("\npTunnel->Reroute %d pTunnel->properties %x",pTunnel->ReRoute,pTunnel->properties);
62014 + else if(pTunnel->ReRoute == FALSE)
62016 + return NULL;
62018 + zlog_info("\nSecondary Tunnel failed Dest %x Tunnel ID %x Source %x",
62019 + pUserLsp->params.to,pTunnel->TunnelId,pUserLsp->params.from);
62020 + return UserSecondaryLspRecovery(pTunnel,pSm,exclude_node);
62024 +uns32 GetTunnelHops(RSVP_TUNNEL_PROPERTIES *pTunnel,uns32 *ErHopNumber,IPV4_ADDR **ppErHops)
62026 + RSVP_LSP_PROPERTIES *pRsvpWorkingLsp;
62027 + IPV4_ADDR *pWorkingRsvpLspErHops = NULL;
62028 + uns32 WorkingRsvpLspHops = 0,i,j;
62030 + zlog_info("entering GetTunnelHops");
62032 + *ErHopNumber = 0;
62033 + *ppErHops = NULL;
62034 + if(pTunnel == NULL)
62036 + return E_ERR;
62038 + if((pRsvpWorkingLsp = GetWorkingRsvpLsp(pTunnel)) != NULL)
62040 + if(pRsvpWorkingLsp->tunneled == FALSE)
62042 + WorkingRsvpLspHops = pRsvpWorkingLsp->forw_info.path.HopCount;
62043 + pWorkingRsvpLspErHops = pRsvpWorkingLsp->forw_info.path.pErHopsList;
62044 +#if 0
62045 + if((pWorkingRsvpLspErHops)&&(pWorkingRsvpLspErHops[WorkingRsvpLspHops-1] == PsbKey.Session.Dest)
62047 + WorkingRsvpLspHops--;
62049 +#endif
62051 + else
62053 + zlog_err("\nthis case is not supported %s %d",__FILE__,__LINE__);
62056 + else
62058 + WorkingRsvpLspHops = 0;
62060 + /* now, fill in the array */
62061 + if(WorkingRsvpLspHops != 0)
62063 + if((*ppErHops = (IPV4_ADDR *)XMALLOC(MTYPE_TE,sizeof(IPV4_ADDR)*(WorkingRsvpLspHops/2))) == NULL)
62065 + zlog_err("\nmalloc failed %s %d",__FILE__,__LINE__);
62066 + return E_ERR;
62068 + for(j = 0,i = 0;i < WorkingRsvpLspHops;i += 2,j++)
62070 + if(rdb_remote_link_router_id_get(pWorkingRsvpLspErHops[i],&((*ppErHops)[j])) != E_OK)
62072 + zlog_err("Cannot get router ID for %x %s %d",pWorkingRsvpLspErHops[i],__FILE__,__LINE__);
62075 + *ErHopNumber = WorkingRsvpLspHops/2;
62077 + zlog_info("leaving GetTunnelHops");
62078 + return E_OK;
62081 +BOOL TunnelsHaveSharedErHops(IPV4_ADDR *pFirstArray,
62082 + uns32 FirstArraySize,
62083 + IPV4_ADDR *pSecondArray,
62084 + uns32 SecondArraySize)
62086 + int i,j;
62087 + for(i = 0;i < FirstArraySize;i++)
62089 + for(j = 0;j < SecondArraySize;j++)
62091 + if(pFirstArray[i] == pSecondArray[j])
62093 + zlog_info("Hop %x is shared",pFirstArray[i]);
62094 + return TRUE;
62098 + return FALSE;
62101 +SM_CALL_T *ModifySecondary(RSVP_TUNNEL_PROPERTIES *pSecTunnel,
62102 + SM_T *pSm,
62103 + STATIC_PATH *pPrimaryStaticPath,
62104 + USER_LSP *pUserLsp)
62106 + INGRESS_API *pOpenLspParams = NULL;
62107 + STATIC_PATH *pSecStaticPath;
62108 + IPV4_ADDR *pSecondaryLspErHops;
62109 + uns32 SecondaryLspErHopNumber;
62110 + LSP_PATH_SHARED_PARAMS *pParams;
62111 + ER_HOP *pErHopsList = NULL;
62112 + IPV4_ADDR *pPrimaryLspErHops;
62113 + uns32 PrimaryLspErHopNumber;
62114 + uns8 Flags = 0;
62116 + zlog_info("entering ModifySecondary");
62117 + if(pSecTunnel == NULL)
62119 + return NULL;
62121 + if(pSecTunnel->ReRoute == TRUE)
62123 + pSecTunnel->AdjustmentRequired = TRUE;
62124 + zlog_info("\nSecondary LSP adjustment is postponed...");
62125 + return NULL;
62127 + if(rdb_get_static_path(pSecTunnel->StaticPathName,
62128 + &pSecStaticPath) == E_OK)
62130 + /* if checking for shared hops makes sense */
62131 + if((((pSecStaticPath->HopList != NULL)&&
62132 + (pSecStaticPath->HopList->Loose == 1))||
62133 + (pSecStaticPath->HopList == NULL))||
62134 + (((pPrimaryStaticPath != NULL)&&
62135 + (pPrimaryStaticPath->HopList != NULL)&&
62136 + (pPrimaryStaticPath->HopList->Loose == 1))||
62137 + ((pPrimaryStaticPath == NULL)||
62138 + (pPrimaryStaticPath->HopList == NULL))))
62140 + if(GetTunnelHops(pSecTunnel,&SecondaryLspErHopNumber,&pSecondaryLspErHops) != E_OK)
62142 + SecondaryLspErHopNumber = 0;
62143 + pSecondaryLspErHops = NULL;
62144 + zlog_info("\ncannot get Secondary Tunnel's ER HOPS");
62146 + if(GetTunnelHops(pUserLsp->pUserLspTunnels,&PrimaryLspErHopNumber,&pPrimaryLspErHops) != E_OK)
62148 + PrimaryLspErHopNumber = 0;
62149 + pPrimaryLspErHops = NULL;
62150 + zlog_info("\ncannot get Primary tunnel's ER HOPs");
62152 + zlog_info("\nSecondary Tunnel's ER HOPS number %d",SecondaryLspErHopNumber);
62153 + if((TunnelsHaveSharedErHops(pPrimaryLspErHops,
62154 + PrimaryLspErHopNumber,
62155 + pSecondaryLspErHops,
62156 + SecondaryLspErHopNumber) == TRUE)||
62157 + (GetWorkingRsvpLsp(pSecTunnel) == NULL))
62159 + zlog_info("\nSTEP1");
62160 + pParams = PathParamsGet(pUserLsp,pSecStaticPath->PathName,0);
62161 + Flags |= (pParams->record == TRUE) ? LABEL_RECORDING_DESIRED : 0;
62162 + /* for now the FRR is only boolean. However, in future it may be more complicated */
62163 + Flags |= (pUserLsp->params.FastReRoute == TRUE) ? LOCAL_PROTECTION_DESIRED : 0;
62164 + if(SetErHopList(pSecStaticPath,&pErHopsList) != E_OK)
62166 + zlog_err("Cannot set ER hops list %s %d",__FILE__,__LINE__);
62167 + return NULL;
62169 + if((pOpenLspParams = CreateRequest2Signalling(pUserLsp->params.to,
62170 + pSecTunnel->TunnelId,
62171 + pSecStaticPath->HopCount,
62172 + pErHopsList,
62173 + pSecTunnel->RequiredBW,
62174 + pParams->setup_priority,
62175 + pParams->hold_priority,
62176 + Flags,
62177 + (~(pParams->affinity_properties & pParams->affinity_mask)) & pParams->affinity_mask,
62178 + 0,
62179 + pParams->affinity_properties & pParams->affinity_mask)) == NULL)
62181 + zlog_err("\nmalloc failed %s %d",__FILE__,__LINE__);
62182 + XFREE(MTYPE_TE,pErHopsList);
62183 + return NULL;
62186 + return LspRequest(pOpenLspParams,PrimaryLspErHopNumber,pPrimaryLspErHops,pSm,&pSecTunnel,TRUE,pParams);
62188 + else
62190 + zlog_info("Tunnels do not have shared hops");
62192 + XFREE(MTYPE_TE,pSecondaryLspErHops);
62194 + else
62196 + zlog_info("\nRoute re-resolution doesn't makes sense %s %x %x",
62197 + pSecStaticPath->PathName,
62198 + pPrimaryStaticPath,pSecStaticPath);
62199 + if((pPrimaryStaticPath != NULL)&&
62200 + (pPrimaryStaticPath->HopList != NULL))
62201 + zlog_info("\nLoose (primary) %d",pPrimaryStaticPath->HopList->Loose);
62202 + if(pSecStaticPath->HopList != NULL)
62203 + zlog_info("\nLoose (secondary) %d",pSecStaticPath->HopList->Loose);
62206 + else
62208 + if(GetTunnelHops(pSecTunnel,&SecondaryLspErHopNumber,&pSecondaryLspErHops) != E_OK)
62210 + SecondaryLspErHopNumber = 0;
62211 + pSecondaryLspErHops = NULL;
62212 + zlog_info("\ncannot get Secondary Tunnel's ER HOPS");
62214 + if(GetTunnelHops(pUserLsp->pUserLspTunnels,&PrimaryLspErHopNumber,&pPrimaryLspErHops) != E_OK)
62216 + PrimaryLspErHopNumber = 0;
62217 + pPrimaryLspErHops = NULL;
62218 + zlog_info("\ncannot get Primary tunnel's ER HOPs");
62220 + zlog_info("\nSecondary Tunnel's ER HOPS number %d",SecondaryLspErHopNumber);
62221 + if((TunnelsHaveSharedErHops(pPrimaryLspErHops,
62222 + PrimaryLspErHopNumber,
62223 + pSecondaryLspErHops,
62224 + SecondaryLspErHopNumber) == TRUE)||
62225 + (GetWorkingRsvpLsp(pSecTunnel) == NULL))
62227 + zlog_info("\nSTEP1`");
62228 + pParams = PathParamsGet(pUserLsp,pSecTunnel->StaticPathName,0);
62229 + Flags |= (pParams->record == TRUE) ? LABEL_RECORDING_DESIRED : 0;
62230 + /* for now the FRR is only boolean. However, in future it may be more complicated */
62231 + Flags |= (pUserLsp->params.FastReRoute == TRUE) ? LOCAL_PROTECTION_DESIRED : 0;
62233 + if((pOpenLspParams = CreateRequest2Signalling(pUserLsp->params.to,
62234 + pSecTunnel->TunnelId,
62235 + 0,
62236 + NULL,
62237 + pSecTunnel->RequiredBW,
62238 + pParams->setup_priority,
62239 + pParams->hold_priority,
62240 + Flags,
62241 + (~(pParams->affinity_properties & pParams->affinity_mask)) & pParams->affinity_mask,
62242 + 0,
62243 + pParams->affinity_properties & pParams->affinity_mask)) == NULL)
62245 + zlog_err("\nmalloc failed %s %d",__FILE__,__LINE__);
62246 + return NULL;
62249 + return LspRequest(pOpenLspParams,PrimaryLspErHopNumber,pPrimaryLspErHops,pSm,&pSecTunnel,TRUE,pParams);
62251 + else
62253 + zlog_info("\nTunnels do not have shared hops");
62255 + XFREE(MTYPE_TE,pSecondaryLspErHops);
62257 + return NULL;
62260 +SM_CALL_T *OptimizeSingleLsp(RSVP_TUNNEL_PROPERTIES *pTunnel,IPV4_ADDR dest,IPV4_ADDR source)
62262 + SM_CALL_T *pCall = NULL;
62263 + LSP_PATH_SHARED_PARAMS *pParams;
62264 + USER_LSP *pUserLsp;
62265 + STATIC_PATH *pStaticPath = NULL;
62266 + uns8 Flags = 0;
62267 + ER_HOP *pErHopsList = NULL;
62268 + RSVP_TUNNEL_PROPERTIES *pDummyTunnel;
62269 + SM_T *pSm;
62270 + INGRESS_API *pOpenLspParams;
62271 + RSVP_LSP_PROPERTIES *pRsvpLsp;
62273 + zlog_info("entering OptimizeSingleLsp");
62274 + pSm = pTunnel->sm_handle;
62275 + UnregisterClient((int)pSm,pTunnel->TunnelId);
62276 + if(pTunnel->pOpenLspParams)
62278 + XFREE(MTYPE_TE,pTunnel->pOpenLspParams);
62279 + pTunnel->pOpenLspParams = NULL;
62281 + if(pTunnel->pCrArgs)
62283 + if((((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->tunneled == FALSE)&&
62284 + (((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->data.path.ErHopNumber))
62286 + XFREE(MTYPE_TE,((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->data.path.pErHop);
62287 + ((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->data.path.pErHop = NULL;
62288 + ((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->data.path.ErHopNumber = 0;
62290 + if(((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->AvoidHopNumber)
62292 + XFREE(MTYPE_TE,((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->AvoidHopsArray);
62293 + ((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->AvoidHopsArray = NULL;
62294 + ((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->AvoidHopNumber = 0;
62296 + if(((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->LinkBwNumber)
62298 + XFREE(MTYPE_TE,((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->pLinkBw);
62299 + ((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->pLinkBw = NULL;
62300 + ((CONSTRAINT_ROUTE_RESOLUTION_ARGS *)(pTunnel->pCrArgs))->LinkBwNumber = 0;
62302 + XFREE(MTYPE_TE,pTunnel->pCrArgs);
62305 + if((pUserLsp = UserLspGet(pTunnel->UserLspName)) != NULL)
62307 + pParams = PathParamsGet(pUserLsp,
62308 + pTunnel->StaticPathName,
62309 + ((!strcmp(pUserLsp->params.Primary,pTunnel->StaticPathName))&&(pUserLsp->pUserLspTunnels->TunnelId == pTunnel->TunnelId)));
62310 + if(rdb_get_static_path(pTunnel->StaticPathName,
62311 + &pStaticPath) != E_OK)
62313 + pStaticPath = NULL;
62315 + if(pStaticPath)
62317 + if(SetErHopList(pStaticPath,&pErHopsList) != E_OK)
62319 + zlog_err("Cannot set ER hops list %s %d",__FILE__,__LINE__);
62320 + return NULL;
62323 + if((pErHopsList != NULL)&&(pErHopsList[0].Loose == 0)) /* nothing to optimize */
62325 + XFREE(MTYPE_TE,pErHopsList);
62326 + return NULL;
62328 + if((pUserLsp->pUserLspTunnels->TunnelId == pTunnel->TunnelId)||(pTunnel->ReRoute == 0))
62330 + uns32 ErHopNumber;
62331 + IPV4_ADDR *pErHops;
62332 + if(pUserLsp->pUserLspTunnels->TunnelId != pTunnel->TunnelId)
62334 + if(GetTunnelHops(pUserLsp->pUserLspTunnels,
62335 + &ErHopNumber,
62336 + &pErHops) != E_OK)
62338 + zlog_info(
62339 + "cannot get ER HOPs to be avoided %s %d",
62340 + __FILE__,__LINE__);
62341 + ErHopNumber = 0;
62342 + pErHops = NULL;
62345 + else
62347 + ErHopNumber = 0;
62348 + pErHops = NULL;
62350 + Flags |= pParams->record == TRUE ? LABEL_RECORDING_DESIRED : 0;
62351 + /* for now the FRR is only boolean. However, in future it may be more complicated */
62352 + Flags |= (pUserLsp->params.FastReRoute == TRUE) ? LOCAL_PROTECTION_DESIRED : 0;
62353 + if((pStaticPath != NULL)&&(SetErHopList(pStaticPath,&pErHopsList) != E_OK))
62355 + zlog_err("Cannot set ER hops list %s %d",__FILE__,__LINE__);
62356 + return NULL;
62358 + if((pOpenLspParams = CreateRequest2Signalling(pUserLsp->params.to,
62359 + pTunnel->TunnelId,
62360 + (pStaticPath == NULL) ? 0 : pStaticPath->HopCount,
62361 + pErHopsList,
62362 + pParams->BW,
62363 + pParams->setup_priority,
62364 + pParams->hold_priority,
62365 + Flags,
62366 + (~(pParams->affinity_properties & pParams->affinity_mask)) & pParams->affinity_mask,
62367 + 0,
62368 + pParams->affinity_properties & pParams->affinity_mask)) == NULL)
62370 + zlog_err("malloc failed %s %d",__FILE__,__LINE__);
62371 + return NULL;
62373 + return LspRequest(pOpenLspParams,
62374 + ErHopNumber,
62375 + pErHops,
62376 + pSm,
62377 + &pDummyTunnel,
62378 + TRUE,
62379 + pParams);
62382 + else if((pRsvpLsp = GetWorkingRsvpLsp(pTunnel)) != NULL)
62384 + Flags |= LABEL_RECORDING_DESIRED;
62385 + /* for now the FRR is only boolean. However, in future it may be more complicated */
62386 + Flags |= LOCAL_PROTECTION_DESIRED;
62387 + if((pOpenLspParams = CreateRequest2Signalling(dest,
62388 + pTunnel->TunnelId,
62389 + 0,
62390 + NULL,
62391 + pTunnel->RequiredBW,
62392 + pRsvpLsp->SetupPriority,
62393 + pRsvpLsp->HoldPriority,
62394 + Flags,
62395 + 0,0,0)) == NULL)
62397 + zlog_err("malloc failed %s %d",__FILE__,__LINE__);
62398 + return NULL;
62400 + return LspRequest(pOpenLspParams,
62401 + 0,
62402 + NULL,
62403 + pSm,
62404 + &pDummyTunnel,
62405 + TRUE,
62406 + NULL);
62408 + StartCspfRetryTimer(pTunnel);
62409 + zlog_info("leaving OptimizeSingleLsp");
62410 + return pCall;
62414 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_lsp.h quagga-mpls/rsvpd/te_lsp.h
62415 --- quagga/rsvpd/te_lsp.h 1969-12-31 18:00:00.000000000 -0600
62416 +++ quagga-mpls/rsvpd/te_lsp.h 2007-06-18 23:55:58.000000000 -0500
62417 @@ -0,0 +1,77 @@
62419 +#ifndef __LSP_SM_H__
62420 +#define __LSP_SM_H__
62422 +typedef enum
62424 + LSP_SM_MAX_STATE = INIT_STATE + 1
62425 +} LSP_SM_STATE_E;
62427 +typedef struct
62429 + TUNNEL_ID_LIST *TunnelIdHead;
62430 +} LSP_SM_DATA;
62432 +typedef enum
62434 + SETUP_COMPLETE_NOTIF,
62435 + SETUP_FAILED_NOTIF,
62436 + TEAR_DOWN_NOTIF
62437 +} LSP_NOTIF_E;
62439 +typedef struct
62441 + uns32 Label;
62442 + uns16 LspId;
62443 +} LSP_LABEL;
62445 +typedef struct
62447 + uns32 NumberOfItems;
62448 + float BW;
62449 + LSP_LABEL *pLspLabel;
62450 +} SETUP_COMPLETE;
62452 +typedef struct
62454 + uns16 LspId;
62455 + IPV4_ADDR IpAddr;
62456 +} SETUP_FAILED;
62458 +typedef struct
62460 + uns32 NumberOfItems;
62461 + union
62463 + uns16 LspId;
62464 + uns16 *pLsps;
62465 + } Lsps;
62466 +} TUNNEL_DOWN_T;
62468 +typedef struct
62470 + PSB_KEY PsbKey;
62471 + LSP_NOTIF_E ingress_lsp_notif;
62472 + union
62474 + SETUP_COMPLETE setup_complete;
62475 + SETUP_FAILED setup_failed;
62476 + TUNNEL_DOWN_T tunnel_down;
62477 + } data;
62478 +} LSP_SM_NOTIF_DATA;
62480 +typedef struct
62482 + IPV4_ADDR dest;
62483 + uns16 tunnel_id;
62484 +} LSP_SM_REPLY;
62486 +SM_CALL_T *lsp_sm_handler (SM_T * pSm, SM_EVENT_T * sm_data);
62488 +SM_CALL_T *lsp_sm_sync_invoke (SM_T * caller, void *data, SM_EVENT_E event);
62490 +RSVP_LSP_PROPERTIES *GetWorkingRsvpLsp (RSVP_TUNNEL_PROPERTIES * pTunnel);
62491 +RSVP_LSP_PROPERTIES *CurrentPathHasAvBw (RSVP_TUNNEL_PROPERTIES * pTunnel,
62492 + float BW);
62494 +#endif
62495 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_rdb.c quagga-mpls/rsvpd/te_rdb.c
62496 --- quagga/rsvpd/te_rdb.c 1969-12-31 18:00:00.000000000 -0600
62497 +++ quagga-mpls/rsvpd/te_rdb.c 2008-02-25 21:07:32.000000000 -0600
62498 @@ -0,0 +1,2854 @@
62499 +/* Module: rdb.c
62500 + Contains: TE application route DB and pach cache
62501 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
62502 + */
62503 +#include "te.h"
62504 +#include "te_cspf.h"
62506 +extern struct zclient *zclient;
62508 +/***********************************************************************************
62509 + ***********************************************************************************
62510 + * *
62511 + * *
62512 + * Routing Database Manager *
62513 + * *
62514 + * *
62515 + ***********************************************************************************
62516 + **********************************************************************************/
62518 +/** This is an Routing Table Entry, created via rdb_add_route wrapper
62519 + **/
62521 +/** This is an IfAddr Table Entry, created via rdb_add_ifaddr
62522 + **/
62523 +typedef struct rdb_ifaddr_tag
62525 + struct rdb_ifaddr_tag *next;
62526 + IPV4_ADDR ip_addr;
62527 + uns32 ifIndex;
62528 +} SYSF_RDB_IFADDR;
62530 +typedef struct
62532 + PATRICIA_NODE Node;
62533 + IPV4_ADDR dest;
62534 + PATH_L_LIST *PathLList;
62535 + uns32 LListItemsCount;
62536 +} RDB_PATH;
62538 +typedef struct
62540 + PATRICIA_NODE Node;
62541 + IPV4_ADDR dest;
62542 + TE_LINK_L_LIST *TELinkLList;
62543 + uns32 LListItemsCount;
62544 +} RDB_NEXT_HOP;
62546 +typedef struct
62548 + PATRICIA_NODE Node;
62549 + IPV4_ADDR neighbor;
62550 +} TE_LINK_NEXT_HOP;
62552 +typedef struct
62554 + PATRICIA_NODE Node;
62555 + IPV4_ADDR dest;
62556 + ABRS_L_LIST *AbrsLList;
62557 + uns32 LListItemsCount;
62558 +} RDB_ABRS;
62560 +/** This is the Routing Database, created via rdb_create wrapper.
62561 + **/
62562 +SYSF_RDB_IFADDR *ifaddr_anchor;
62563 +PATRICIA_TREE ASBorderTree;
62564 +PATRICIA_TREE AreaBorderTree;
62565 +PATRICIA_TREE NextHopTree;
62566 +TE_LINK_L_LIST *TeLinkLListHead;
62567 +PATRICIA_TREE RemoteLinkTree[MAX_PATH_TYPE - 1];
62568 +PATRICIA_TREE Link2RouterIdTree;
62569 +STATIC_PATH *StaticPathHead;
62570 +IPV4_ADDR RouterID = 0;
62572 +static uns32 compare_er_hops (ER_HOP_L_LIST * er_hops1, TE_HOP * er_hops2,
62573 + uns8 hop_count);
62575 +static void copy_te_link (TE_LINK * te_link1, TE_LINK * te_link2);
62577 +static void delete_te_link (TE_LINK * te_link);
62579 +static void delete_abr (ABR * pAbr);
62580 +static void delete_component_link (COMPONENT_LINK * pComponentLink);
62582 +uns32
62583 +AmIDestination (IPV4_ADDR dest, uns32 * pDestIf)
62585 + SYSF_RDB_IFADDR *ifaddr;
62587 + *pDestIf = 0xFFFFFFFF;
62589 + for (ifaddr = ifaddr_anchor; ifaddr != NULL; ifaddr = ifaddr->next)
62591 + if (ifaddr->ip_addr == dest)
62593 + *pDestIf = ifaddr->ifIndex;
62594 + break;
62597 + return E_OK;
62600 +uns32
62601 +IsDestinationNextHop (IPV4_ADDR dest, TE_LINK_L_LIST ** ppTeLinks)
62603 + RDB_NEXT_HOP *next_hop_entry;
62606 + if ((next_hop_entry =
62607 + (RDB_NEXT_HOP *) patricia_tree_get (&NextHopTree,
62608 + (const uns8 *) &dest)) != NULL)
62610 + *ppTeLinks = next_hop_entry->TELinkLList;
62612 + else
62614 + *ppTeLinks = NULL;
62616 + return E_OK;
62619 +uns32
62620 +IsDestinationIntraArea (IPV4_ADDR dest, PATH_L_LIST ** ppPaths)
62622 + RDB_PATH *path_entry;
62624 + if ((path_entry =
62625 + (RDB_PATH *) patricia_tree_get (&AreaBorderTree,
62626 + (const uns8 *) &dest)) != NULL)
62628 + *ppPaths = path_entry->PathLList;
62630 + else
62632 + *ppPaths = NULL;
62634 + return E_OK;
62637 +uns32
62638 +GetPathNumber (IPV4_ADDR dest)
62640 + RDB_PATH *path_entry;
62642 + if ((path_entry =
62643 + (RDB_PATH *) patricia_tree_get (&AreaBorderTree,
62644 + (const uns8 *) &dest)) != NULL)
62646 + return path_entry->LListItemsCount;
62648 + return 0;
62651 +uns32
62652 +IsDestinationASBorder (IPV4_ADDR dest, ABRS_L_LIST ** ppAbrs)
62654 + RDB_ABRS *abr_entry;
62656 + if ((abr_entry =
62657 + (RDB_ABRS *) patricia_tree_get (&ASBorderTree,
62658 + (const uns8 *) &dest)) != NULL)
62660 + *ppAbrs = abr_entry->AbrsLList;
62662 + else
62664 + *ppAbrs = NULL;
62666 + return E_OK;
62669 +/*****************************************************************************
62671 + PROCEDURE NAME: rdb_create
62673 + DESCRIPTION:
62675 + Creates a routing database.
62677 +*****************************************************************************/
62678 +E_RC
62679 +rdb_create ()
62681 + PATRICIA_PARAMS params;
62682 + int i;
62683 + memset (&params, 0, sizeof (params));
62684 + params.key_size = sizeof (IPV4_ADDR);
62685 + params.info_size = 0;
62687 + TeLinkLListHead = NULL;
62688 + ifaddr_anchor = NULL;
62690 + if (patricia_tree_init (&AreaBorderTree, &params) != E_OK)
62692 + return E_ERR;
62694 + if (patricia_tree_init (&ASBorderTree, &params) != E_OK)
62696 + return E_ERR;
62698 + if (patricia_tree_init (&NextHopTree, &params) != E_OK)
62700 + return E_ERR;
62703 + if (patricia_tree_init (&Link2RouterIdTree, &params) != E_OK)
62705 + return E_ERR;
62708 + params.key_size = sizeof (IPV4_ADDR) + sizeof (IPV4_ADDR);
62709 + params.info_size = 0;
62711 + for (i = 0; i < (MAX_PATH_TYPE - 1); i++)
62713 + if (patricia_tree_init (&(RemoteLinkTree[i]), &params) != E_OK)
62715 + return E_ERR;
62719 + StaticPathHead = NULL;
62721 + return E_OK;
62725 +/*****************************************************************************
62727 + PROCEDURE NAME: rdb_destroy
62729 + DESCRIPTION:
62732 +*****************************************************************************/
62733 +uns32
62734 +rdb_destroy ()
62736 + RDB_PATH *path_entry;
62737 + RDB_NEXT_HOP *next_hop_entry;
62738 + RDB_ABRS *abr_entry;
62739 + IPV4_ADDR key_ip;
62741 + key_ip = 0;
62742 + while ((abr_entry =
62743 + (RDB_ABRS *) patricia_tree_getnext (&ASBorderTree,
62744 + (const uns8 *) &key_ip)) !=
62745 + NULL)
62747 + while (abr_entry->AbrsLList != NULL)
62749 + ABRS_L_LIST *pAbrLl = abr_entry->AbrsLList->next;
62750 + XFREE (MTYPE_TE, abr_entry->AbrsLList->Abr->SummaryProperties);
62751 + XFREE (MTYPE_TE, abr_entry->AbrsLList->Abr);
62752 + XFREE (MTYPE_TE, abr_entry->AbrsLList);
62753 + abr_entry->AbrsLList = pAbrLl;
62755 + key_ip = abr_entry->dest;
62756 + if (patricia_tree_del (&ASBorderTree, &abr_entry->Node) != E_OK)
62758 + zlog_err ("\ncannot delete ASBR");
62761 + patricia_tree_destroy (&ASBorderTree);
62762 + key_ip = 0;
62763 + while ((path_entry =
62764 + (RDB_PATH *) patricia_tree_getnext (&AreaBorderTree,
62765 + (const uns8 *) &key_ip)) !=
62766 + NULL)
62768 + while (path_entry->PathLList != NULL)
62770 + PATH_L_LIST *pPathLl = path_entry->PathLList->next;
62771 + XFREE (MTYPE_TE, path_entry->PathLList->pPath->u.er_hops);
62772 + XFREE (MTYPE_TE, path_entry->PathLList->pPath);
62773 + XFREE (MTYPE_TE, path_entry->PathLList);
62774 + path_entry->PathLList = pPathLl;
62776 + key_ip = path_entry->dest;
62777 + if (patricia_tree_del (&AreaBorderTree, &path_entry->Node) != E_OK)
62779 + zlog_err ("\ncannot delete ASBR");
62782 + patricia_tree_destroy (&AreaBorderTree);
62783 + key_ip = 0;
62784 + while ((next_hop_entry =
62785 + (RDB_NEXT_HOP *) patricia_tree_getnext (&NextHopTree,
62786 + (const uns8 *) &key_ip)) !=
62787 + NULL)
62789 + while (next_hop_entry->TELinkLList != NULL)
62791 + TE_LINK_L_LIST *pTeLinkLl = next_hop_entry->TELinkLList->next;
62792 + XFREE (MTYPE_TE, next_hop_entry->TELinkLList);
62793 + next_hop_entry->TELinkLList = pTeLinkLl;
62795 + key_ip = next_hop_entry->dest;
62796 + if (patricia_tree_del (&NextHopTree, &next_hop_entry->Node) != E_OK)
62798 + zlog_err ("\ncannot delete ASBR");
62801 + patricia_tree_destroy (&NextHopTree);
62802 + return E_OK;
62805 +uns32
62806 +compare_er_hops (ER_HOP_L_LIST * er_hops1, TE_HOP * er_hops2, uns8 hop_count)
62808 + int i;
62809 + for (i = 0; i < hop_count; i++)
62811 + if ((er_hops1->er_hop->local_ip != er_hops2->local_ip) ||
62812 + (er_hops1->er_hop->remote_ip != er_hops2->remote_ip))
62813 + return FALSE;
62814 + er_hops1 = er_hops1->next;
62815 + er_hops2++;
62817 + return TRUE;
62820 +void
62821 +copy_te_link (TE_LINK * te_link1, TE_LINK * te_link2)
62823 + COMPONENT_LINK *pComponentLink1, *pComponentLink2, *pTemp;
62824 + int j;
62826 + te_link1->te_link_id = te_link2->te_link_id;
62827 + te_link1->Status = te_link2->Status;
62828 + te_link1->type = te_link2->type;
62829 + memcpy (&te_link1->te_link_properties, &te_link2->te_link_properties,
62830 + sizeof (TE_LINK_PROPERTIES));
62831 + pComponentLink1 = te_link1->component_links;
62832 + pComponentLink2 = te_link2->component_links;
62833 + while ((pComponentLink1 != NULL) && (pComponentLink2 != NULL))
62835 + pComponentLink1->oifIndex = pComponentLink2->oifIndex;
62836 +// pComponentLink1->vcard_id = pComponentLink2->vcard_id;
62837 + for (j = 0; j < 8; j++)
62839 + pComponentLink1->ReservableBW[j] = pComponentLink2->ReservableBW[j];
62840 + pComponentLink1->ConfiguredReservableBW[j] =
62841 + pComponentLink2->ConfiguredReservableBW[j];
62843 + pComponentLink1 = pComponentLink1->next;
62844 + pComponentLink2 = pComponentLink2->next;
62846 + if ((pComponentLink1 == NULL) && (pComponentLink2 != NULL))
62848 + while (pComponentLink2 != NULL)
62850 + pTemp = pComponentLink2->next;
62851 + pComponentLink2->next = te_link1->component_links;
62852 + te_link1->component_links = pComponentLink2;
62853 + pComponentLink2 = pTemp;
62856 + else if ((pComponentLink1 != NULL) && (pComponentLink2 == NULL))
62858 + while (pComponentLink1 != NULL)
62860 + pTemp = pComponentLink1->next;
62861 + delete_component_link (pComponentLink1);
62862 + pComponentLink1 = pTemp;
62868 +void
62869 +delete_component_link (COMPONENT_LINK * pComponentLink)
62871 + XFREE (MTYPE_TE, pComponentLink);
62874 +void
62875 +delete_te_link (TE_LINK * te_link)
62877 + COMPONENT_LINK *pComponentLink;
62879 + while (te_link->component_links != NULL)
62881 + pComponentLink = te_link->component_links->next;
62882 + delete_component_link (te_link->component_links);
62883 + te_link->component_links = pComponentLink;
62885 + XFREE (MTYPE_TE, te_link);
62888 +void
62889 +delete_abr (ABR * pAbr)
62891 + XFREE (MTYPE_TE, pAbr->SummaryProperties);
62892 + XFREE (MTYPE_TE, pAbr);
62893 + return;
62896 +/*****************************************************************************
62898 + PROCEDURE NAME: rdb_add_component_link
62900 + DESCRIPTION: The routine adds a new TE link into TE links linked links.
62902 + PARAMETERS: rdb_handle - Routing Data Base handler
62903 + pTeLink - pointer to TE Link's properties (may span component links).
62904 + IMPORTANT NOTE: The memory for pTeLink MUST be allocated from HEAP (not on the stack!!!).
62906 +*****************************************************************************/
62908 +uns32
62909 +rdb_add_component_link (uns32 TeLinkId, COMPONENT_LINK * pComponentLink)
62911 + TE_LINK_L_LIST *pTeLinks;
62912 + COMPONENT_LINK *pTemp;
62913 + int j;
62914 + float MaxReservableBW = 0;
62916 + pTeLinks = TeLinkLListHead;
62917 + while (pTeLinks != NULL)
62919 + if (pTeLinks->te_link->te_link_id == TeLinkId)
62921 + while (pComponentLink != NULL)
62923 + pTemp = pComponentLink->next;
62924 + pComponentLink->next = pTeLinks->te_link->component_links;
62925 + pTeLinks->te_link->component_links = pComponentLink;
62926 + for (j = 0; j < 8; j++)
62928 + pTeLinks->te_link->te_link_properties.ReservableBW[j] +=
62929 + pComponentLink->ReservableBW[j];
62930 + if (pComponentLink->ReservableBW[j] > MaxReservableBW)
62931 + MaxReservableBW = pComponentLink->ReservableBW[j];
62933 + pComponentLink = pTemp;
62935 + break;
62937 + pTeLinks = pTeLinks->next;
62939 + if (pTeLinks == NULL)
62941 + zlog_err ("\nTE link was not found");
62942 + return E_ERR;
62944 + if (pTeLinks->te_link->te_link_properties.MaxReservableBW < MaxReservableBW)
62945 + pTeLinks->te_link->te_link_properties.MaxReservableBW = MaxReservableBW;
62946 + return E_OK;
62949 +/*****************************************************************************
62951 + PROCEDURE NAME: rdb_delete_component_link
62953 + DESCRIPTION: The routine adds a new TE link into TE links linked links.
62955 + PARAMETERS: rdb_handle - Routing Data Base handler
62956 + pTeLink - pointer to TE Link's properties (may span component links).
62957 + IMPORTANT NOTE: The memory for pTeLink MUST be allocated from HEAP (not on the stack!!!).
62959 +*****************************************************************************/
62961 +uns32
62962 +rdb_delete_component_link (uns32 TeLinkId, uns32 oIfIndex)
62964 + TE_LINK_L_LIST *pTeLinks;
62965 + COMPONENT_LINK *pComponentLink, *pComponentLinkPrev;
62966 + BOOL delete_te_link = 0;
62967 + int j;
62969 + pTeLinks = TeLinkLListHead;
62970 + while (pTeLinks != NULL)
62972 + if (pTeLinks->te_link->te_link_id == TeLinkId)
62974 + pComponentLink = pComponentLinkPrev =
62975 + pTeLinks->te_link->component_links;
62976 + while (pComponentLink != NULL)
62978 + if (pComponentLink->oifIndex == oIfIndex)
62980 + for (j = 0; j < 8; j++)
62981 + pTeLinks->te_link->te_link_properties.ReservableBW[j] -=
62982 + pComponentLink->ReservableBW[j];
62983 + if (pComponentLink == pTeLinks->te_link->component_links)
62984 + pTeLinks->te_link->component_links =
62985 + pTeLinks->te_link->component_links->next;
62986 + else
62987 + pComponentLinkPrev->next = pComponentLink->next;
62988 + delete_component_link (pComponentLink);
62989 + if (pTeLinks->te_link->component_links == NULL)
62990 + delete_te_link = 1;
62991 + break;
62993 + pComponentLinkPrev = pComponentLink;
62994 + pComponentLink = pComponentLink->next;
62996 + break;
62998 + pTeLinks = pTeLinks->next;
63000 + if (pTeLinks == NULL)
63002 + zlog_err ("\nTE link was not found");
63003 + return E_ERR;
63005 + if (!delete_te_link)
63007 + rdb_te_link_max_lsp_bw_calc (pTeLinks->te_link);
63009 + if (delete_te_link)
63010 + return rdb_del_te_link (TeLinkId);
63011 + return E_OK;
63014 +/*****************************************************************************
63016 + PROCEDURE NAME: rdb_get_te_link
63018 + DESCRIPTION: The routine gets a component link with IfIndex, belonging to TE Link with TeLinkId.
63020 + PARAMETERS: rdb_handle - Routing Data Base handler
63021 + ppTeLink - pointer to TE Link.
63022 + TeLinkId - TE Link identifier.
63023 + IfIndex - If index.
63024 + IMPORTANT NOTE: The memory for pTeLink MUST be allocated from HEAP (not on the stack!!!).
63026 +*****************************************************************************/
63028 +uns32
63029 +rdb_get_component_link (uns32 TeLinkId, uns32 IfIndex,
63030 + COMPONENT_LINK ** ppCompLink)
63032 + TE_LINK_L_LIST *pTeLinks;
63033 + COMPONENT_LINK *pComponentLinks;
63034 + zlog_info ("entering rdb_get_component_link");
63035 + *ppCompLink = NULL;
63036 + pTeLinks = TeLinkLListHead;
63037 + while (pTeLinks != NULL)
63039 + if (pTeLinks->te_link->te_link_id == TeLinkId)
63041 + pComponentLinks = pTeLinks->te_link->component_links;
63042 + while (pComponentLinks != NULL)
63044 + if (pComponentLinks->oifIndex == IfIndex)
63046 + *ppCompLink = pComponentLinks;
63047 + zlog_info ("leaving rdb_get_component_link+");
63048 + return E_OK;
63050 + pComponentLinks = pComponentLinks->next;
63053 + pTeLinks = pTeLinks->next;
63055 + zlog_info ("leaving rdb_get_component_link-");
63056 + return E_ERR;
63059 +/*****************************************************************************
63061 + PROCEDURE NAME: rdb_get_te_link
63063 + DESCRIPTION: The routine gets a component link with IfIndex, belonging to TE Link with TeLinkId.
63065 + PARAMETERS: rdb_handle - Routing Data Base handler
63066 + ppTeLink - pointer to TE Link.
63067 + TeLinkId - TE Link identifier.
63068 + IfIndex - If index.
63069 + IMPORTANT NOTE: The memory for pTeLink MUST be allocated from HEAP (not on the stack!!!).
63071 +*****************************************************************************/
63073 +uns32
63074 +rdb_get_te_link (uns32 TeLinkId, TE_LINK ** ppTeLink)
63076 + TE_LINK_L_LIST *pTeLinks;
63078 + *ppTeLink = NULL;
63080 + pTeLinks = TeLinkLListHead;
63081 + while (pTeLinks != NULL)
63083 + if (pTeLinks->te_link->te_link_id == TeLinkId)
63085 + *ppTeLink = pTeLinks->te_link;
63086 + return E_OK;
63088 + pTeLinks = pTeLinks->next;
63090 + return E_ERR;
63093 +/*****************************************************************************
63095 + PROCEDURE NAME: rdb_add_te_link
63097 + DESCRIPTION: The routine adds a new TE link into TE links linked links.
63099 + PARAMETERS: rdb_handle - Routing Data Base handler
63100 + pTeLink - pointer to TE Link's properties (may span component links).
63101 + IMPORTANT NOTE: The memory for pTeLink MUST be allocated from HEAP (not on the stack!!!).
63103 +*****************************************************************************/
63105 +void
63106 +rdb_te_link_max_lsp_bw_calc (TE_LINK * pTeLink)
63108 + float MaxReservableBW = 0;
63109 + int j;
63110 + COMPONENT_LINK *pComponentLink = pTeLink->component_links;
63111 + while (pComponentLink != NULL)
63113 + for (j = 0; j < 8; j++)
63115 + if (pComponentLink->ReservableBW[j] > MaxReservableBW)
63116 + MaxReservableBW = pComponentLink->ReservableBW[j];
63118 + pComponentLink = pComponentLink->next;
63120 + pTeLink->te_link_properties.MaxReservableBW = MaxReservableBW;
63121 + return;
63124 +/*****************************************************************************
63126 + PROCEDURE NAME: rdb_add_te_link
63128 + DESCRIPTION: The routine adds a new TE link into TE links linked links.
63130 + PARAMETERS: rdb_handle - Routing Data Base handler
63131 + pTeLink - pointer to TE Link's properties (may span component links).
63132 + IMPORTANT NOTE: The memory for pTeLink MUST be allocated from HEAP (not on the stack!!!).
63134 +*****************************************************************************/
63136 +uns32
63137 +rdb_add_te_link (TE_LINK * pTeLink)
63139 + TE_LINK_L_LIST *pTeLinks, *pTeLinksPrev = NULL, *pNew;
63140 + PATRICIA_PARAMS params;
63142 + zlog_info
63143 + ("entering rdb_add_te_link: TE link ID %x Metric %d Colors %x BW %f",
63144 + pTeLink->te_link_id, pTeLink->te_link_properties.TeMetric,
63145 + pTeLink->te_link_properties.color_mask,
63146 + pTeLink->te_link_properties.MaxLspBW);
63148 + if ((pNew =
63149 + (TE_LINK_L_LIST *) XMALLOC (MTYPE_TE,
63150 + sizeof (TE_LINK_L_LIST))) == NULL)
63152 + delete_te_link (pTeLink);
63153 + return E_ERR;
63155 + pNew->te_link = pTeLink;
63156 + pNew->next = NULL;
63158 + memset (&params, 0, sizeof (params));
63159 + params.key_size = sizeof (IPV4_ADDR);
63160 + params.info_size = 0;
63162 + if (patricia_tree_init (&pTeLink->NeighborsTree, &params) != E_OK)
63164 + XFREE (MTYPE_TE, pNew);
63165 + return E_ERR;
63168 + if (TeLinkLListHead == NULL)
63170 + TeLinkLListHead = pNew;
63171 + zlog_info ("leaving rdb_add_te_link1");
63172 + return E_OK;
63174 + else
63176 + pTeLinks = TeLinkLListHead;
63177 + while (pTeLinks != NULL)
63179 + if (pTeLinks->te_link->te_link_id > pTeLink->te_link_id)
63181 + if (pTeLinks == TeLinkLListHead)
63183 + pNew->next = TeLinkLListHead;
63184 + TeLinkLListHead = pNew;
63186 + else
63188 + pTeLinksPrev->next = pNew;
63189 + pNew->next = pTeLinks;
63191 + zlog_info ("leaving rdb_add_te_link2");
63192 + return E_OK;
63194 + else if (pTeLinks->te_link->te_link_id == pTeLink->te_link_id)
63196 + copy_te_link (pTeLinks->te_link, pTeLink);
63197 + delete_te_link (pTeLink);
63198 + XFREE (MTYPE_TE, pNew);
63199 + zlog_info ("leaving rdb_add_te_link3");
63200 + return E_OK;
63202 + pTeLinksPrev = pTeLinks;
63203 + pTeLinks = pTeLinks->next;
63205 + pTeLinksPrev->next = pNew;
63206 + zlog_info ("leaving rdb_add_te_link4");
63207 + return E_OK;
63211 +/*****************************************************************************
63213 + PROCEDURE NAME: rdb_del_te_link
63215 + DESCRIPTION: The routine deletes the TE link with ID - te_link_id from the
63216 + TE link's linked list.
63218 + PARAMETERS: rdb_handle - Routing Data Base handle.
63219 + te_link_id - TE link ID, by which TE link is found and deleted.
63221 +*****************************************************************************/
63223 +uns32
63224 +rdb_del_te_link (uns32 te_link_id)
63226 + TE_LINK_L_LIST *pTeLink, *pPrev;
63227 + TE_LINK_NEXT_HOP *pTeLinkNextHop;
63228 + uns32 key = 0;
63230 + zlog_info ("entering rdb_del_te_link: TE link ID %x", te_link_id);
63232 + pPrev = pTeLink = TeLinkLListHead;
63233 + while (pTeLink != NULL)
63235 + if (pTeLink->te_link->te_link_id == te_link_id)
63236 + break;
63237 + pPrev = pTeLink;
63238 + pTeLink = pTeLink->next;
63240 + if (pTeLink == NULL)
63242 + return E_ERR;
63245 + if (pPrev == pTeLink)
63247 + TeLinkLListHead = TeLinkLListHead->next;
63249 + else
63251 + pPrev->next = pTeLink->next;
63253 + while ((pTeLinkNextHop =
63254 + (TE_LINK_NEXT_HOP *) patricia_tree_getnext (&pTeLink->te_link->
63255 + NeighborsTree,
63256 + (uns8 *) & key)) !=
63257 + NULL)
63259 + key = pTeLinkNextHop->neighbor;
63260 + rdb_del_next_hop (pTeLinkNextHop->neighbor,
63261 + pTeLink->te_link->te_link_id);
63263 + delete_te_link (pTeLink->te_link);
63264 + XFREE (MTYPE_TE, pTeLink);
63265 + zlog_info ("leaving rdb_del_te_link");
63266 + return E_OK;
63269 +/*****************************************************************************
63271 + PROCEDURE NAME: rdb_add_next_hop
63273 + DESCRIPTION: The routine associates the TE link with ID - te_link_id with
63274 + the next hop next_hop.
63276 + PARAMETERS: rdb_handle - Routing Data Base handle.
63277 + next_hop - Next Hop's IP address.
63278 + TeLinkId - TE link ID, by which TE link is found and associated.
63280 +*****************************************************************************/
63282 +uns32
63283 +rdb_add_next_hop (IPV4_ADDR next_hop, uns32 TeLinkId)
63285 + RDB_NEXT_HOP *next_hop_entry;
63286 + TE_LINK_L_LIST *pPrevTeLink, *pTeLinkLList, *pNew, *pTeLinkLList2;
63287 + TE_LINK_NEXT_HOP *pTeLinkNextHop;
63289 + zlog_info ("entering rdb_add_next_hop: next hop %x TE link ID %x", next_hop,
63290 + TeLinkId);
63292 + pTeLinkLList = TeLinkLListHead;
63293 + while (pTeLinkLList != NULL)
63295 + if (pTeLinkLList->te_link->te_link_id == TeLinkId)
63296 + break;
63297 + pTeLinkLList = pTeLinkLList->next;
63299 + if (pTeLinkLList == NULL)
63301 + zlog_err ("an error at %s %d", __FILE__, __LINE__);
63302 + return E_ERR;
63305 + if ((pNew =
63306 + (TE_LINK_L_LIST *) XMALLOC (MTYPE_TE,
63307 + sizeof (TE_LINK_L_LIST))) == NULL)
63309 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
63310 + return E_ERR;
63312 + pNew->te_link = pTeLinkLList->te_link;
63314 + if ((pTeLinkNextHop =
63315 + (TE_LINK_NEXT_HOP *) XMALLOC (MTYPE_TE,
63316 + sizeof (TE_LINK_NEXT_HOP))) == NULL)
63318 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
63319 + XFREE (MTYPE_TE, pNew);
63320 + return E_ERR;
63322 + pTeLinkNextHop->neighbor = next_hop;
63323 + pTeLinkNextHop->Node.key_info = (uns8 *) & pTeLinkNextHop->neighbor;
63324 + if (patricia_tree_add (&pNew->te_link->NeighborsTree, &pTeLinkNextHop->Node)
63325 + != E_OK)
63327 + XFREE (MTYPE_TE, pNew);
63328 + XFREE (MTYPE_TE, pTeLinkNextHop);
63329 + zlog_err ("an error at %s %d", __FILE__, __LINE__);
63330 + return E_ERR;
63333 + if ((next_hop_entry =
63334 + (RDB_NEXT_HOP *) patricia_tree_get (&NextHopTree,
63335 + (const uns8 *) &next_hop)) == NULL)
63337 + if ((next_hop_entry =
63338 + (RDB_NEXT_HOP *) XMALLOC (MTYPE_TE,
63339 + sizeof (RDB_NEXT_HOP))) == NULL)
63341 + zlog_err ("an error at %s %d", __FILE__, __LINE__);
63342 + XFREE (MTYPE_TE, pNew);
63343 + return E_ERR;
63346 + next_hop_entry->dest = next_hop;
63347 + next_hop_entry->Node.key_info = (uns8 *) & next_hop_entry->dest;
63349 + next_hop_entry->TELinkLList = pNew;
63350 + next_hop_entry->LListItemsCount = 1;
63352 + if (patricia_tree_add (&NextHopTree, &next_hop_entry->Node) != E_OK)
63354 + XFREE (MTYPE_TE, next_hop_entry->TELinkLList);
63355 + XFREE (MTYPE_TE, next_hop_entry);
63356 + XFREE (MTYPE_TE, pNew);
63357 + zlog_err ("an error at %s %d", __FILE__, __LINE__);
63358 + return E_ERR;
63360 + zlog_info ("leaving rdb_add_next_hop1+");
63361 + return E_OK;
63363 + else
63365 + pTeLinkLList2 = next_hop_entry->TELinkLList;
63366 + pPrevTeLink = pTeLinkLList2;
63367 + while (pTeLinkLList2 != NULL)
63369 + if (pTeLinkLList2->te_link->te_link_id == TeLinkId)
63371 + if (patricia_tree_del
63372 + (&pNew->te_link->NeighborsTree,
63373 + &pTeLinkNextHop->Node) != E_OK)
63375 + zlog_err ("an error at %s %d", __FILE__, __LINE__);
63376 + return E_ERR;
63378 + XFREE (MTYPE_TE, pTeLinkNextHop);
63379 + XFREE (MTYPE_TE, pNew);
63380 + zlog_info ("leaving rdb_add_next_hop2+");
63381 + return E_OK;
63383 + else if (pTeLinkLList2->te_link->te_link_id > TeLinkId)
63385 + if (pTeLinkLList2 == pPrevTeLink)
63387 + next_hop_entry->TELinkLList = pNew;
63388 + pNew->next = pTeLinkLList2;
63390 + else
63392 + pNew->next = pTeLinkLList2;
63393 + pPrevTeLink->next = pNew;
63395 + next_hop_entry->LListItemsCount++;
63396 + zlog_info ("leaving rdb_add_next_hop3+");
63397 + return E_OK;
63399 + pPrevTeLink = pTeLinkLList2;
63400 + pTeLinkLList2 = pTeLinkLList2->next;
63401 + } /* of while */
63403 + /* if this point is reached, TE link is new and should be inserted */
63404 + pPrevTeLink->next = pNew;
63405 + next_hop_entry->LListItemsCount++;
63406 + zlog_info ("leaving rdb_add_next_hop4+");
63407 + return E_OK;
63409 + /* should not be reached */
63410 + zlog_err ("an error at %s %d", __FILE__, __LINE__);
63411 + XFREE (MTYPE_TE, pNew);
63412 + return E_ERR;
63415 +/*****************************************************************************
63417 + PROCEDURE NAME: rdb_local_link_down
63419 + DESCRIPTION: The routine deletes the association of TE link with ID - TeLinkId with
63420 + it's next hop.
63422 + PARAMETERS: rdb_handle - Routing Data Base handle.
63423 + TeLinkId - TE link ID, by which TE link is found.
63425 +*****************************************************************************/
63427 +uns32
63428 +rdb_local_link_status_change (uns32 TeLinkId, uns8 Status)
63430 + TE_LINK_L_LIST *pTeLinkLList;
63431 + zlog_info ("entering rdb_local_link_status_change: TE link ID %x status %x",
63432 + TeLinkId, Status);
63433 + pTeLinkLList = TeLinkLListHead;
63434 + while (pTeLinkLList != NULL)
63436 + if (pTeLinkLList->te_link->te_link_id == TeLinkId)
63437 + break;
63438 + pTeLinkLList = pTeLinkLList->next;
63440 + if (pTeLinkLList == NULL)
63442 + return E_ERR;
63445 + pTeLinkLList->te_link->Status = Status;
63446 + zlog_info ("leaving rdb_local_link_status_change");
63447 + return E_OK;
63450 +/*****************************************************************************
63452 + PROCEDURE NAME: rdb_del_next_hop
63454 + DESCRIPTION: The routine deletes the next hop next_hop.
63456 + PARAMETERS: rdb_handle - Routing Data Base handle.
63457 + next_hop - Next Hop's IP address.
63459 +*****************************************************************************/
63461 +uns32
63462 +rdb_del_next_hop (IPV4_ADDR next_hop, uns32 te_link_id)
63464 + RDB_NEXT_HOP *next_hop_entry;
63465 + TE_LINK_L_LIST *pTeLink, *pTeLinkPrev = NULL;
63466 + TE_LINK_NEXT_HOP *pTeLinkNextHop;
63468 + zlog_info ("entering rdb_del_next_hop: next hop %x TE link ID %x", next_hop,
63469 + te_link_id);
63471 + if ((next_hop_entry =
63472 + (RDB_NEXT_HOP *) patricia_tree_get (&NextHopTree,
63473 + (const uns8 *) &next_hop)) == NULL)
63475 + return E_ERR;
63477 + pTeLink = TeLinkLListHead;
63478 + while (pTeLink != NULL)
63480 + if (pTeLink->te_link->te_link_id == te_link_id)
63482 + break;
63484 + pTeLink = pTeLink->next;
63486 + if (pTeLink != NULL)
63488 + if ((pTeLinkNextHop =
63489 + (TE_LINK_NEXT_HOP *) patricia_tree_get (&pTeLink->te_link->
63490 + NeighborsTree,
63491 + (const uns8 *) &next_hop))
63492 + != NULL)
63494 + if (patricia_tree_del
63495 + (&pTeLink->te_link->NeighborsTree,
63496 + &pTeLinkNextHop->Node) == E_OK)
63498 + XFREE (MTYPE_TE, pTeLinkNextHop);
63502 + pTeLink = next_hop_entry->TELinkLList;
63503 + while (pTeLink != NULL)
63505 + if (pTeLink->te_link->te_link_id == te_link_id)
63507 + if (pTeLinkPrev == NULL)
63509 + next_hop_entry->TELinkLList = next_hop_entry->TELinkLList->next;
63511 + else
63513 + pTeLinkPrev->next = pTeLink->next;
63515 + XFREE (MTYPE_TE, pTeLink);
63516 + break;
63518 + pTeLink = pTeLink->next;
63520 + if (next_hop_entry->TELinkLList == NULL)
63522 + if (patricia_tree_del (&NextHopTree, &next_hop_entry->Node) != E_OK)
63524 + return E_ERR;
63526 + XFREE (MTYPE_TE, next_hop_entry);
63528 + zlog_info ("leaving rdb_del_next_hop");
63529 + return E_OK;
63532 +/*****************************************************************************
63534 + PROCEDURE NAME: rdb_add_mod_summary
63536 + DESCRIPTION: The routine adds the summary advertisement to AS border router asbr_ip.
63538 + PARAMETERS: rdb_handle - Routing Data Base handle.
63539 + asbr_ip - AS border's IP address.
63540 + *pAbr - pointer to Area Border structure, which contains Area Border's IP
63541 + and summary attributes to AS border.
63543 +*****************************************************************************/
63544 +uns32
63545 +rdb_add_mod_summary (IPV4_ADDR asbr_ip, ABR * pAbr)
63547 + RDB_ABRS *abr_entry;
63548 + ABRS_L_LIST *pAbrsLList, *pAbrsLListPrev, *pNew;
63550 + if ((pNew =
63551 + (ABRS_L_LIST *) XMALLOC (MTYPE_TE, sizeof (ABRS_L_LIST))) == NULL)
63553 + delete_abr (pAbr);
63554 + zlog_err ("\nFatal at %s %d", __FILE__, __LINE__);
63555 + return E_ERR;
63557 + pNew->Abr = pAbr;
63558 + pNew->next = NULL;
63560 + if ((abr_entry =
63561 + (RDB_ABRS *) patricia_tree_get (&ASBorderTree,
63562 + (const uns8 *) &asbr_ip)) == NULL)
63564 + if ((abr_entry =
63565 + (RDB_ABRS *) XMALLOC (MTYPE_TE, sizeof (RDB_ABRS))) == NULL)
63567 + delete_abr (pAbr);
63568 + return E_ERR;
63571 + /* Initialize new ASBR */
63572 + abr_entry->dest = asbr_ip;
63573 + abr_entry->Node.key_info = (uns8 *) & abr_entry->dest;
63575 + abr_entry->LListItemsCount = 1;
63577 + /* Initialize new and first ABR to ASBR */
63578 + abr_entry->AbrsLList = pNew;
63579 + if (patricia_tree_add (&ASBorderTree, &abr_entry->Node) != E_OK)
63581 + XFREE (MTYPE_TE, abr_entry->AbrsLList);
63582 + XFREE (MTYPE_TE, abr_entry);
63583 + XFREE (MTYPE_TE, pNew);
63584 + return E_ERR;
63586 + return E_OK;
63588 + /* There is such ASBR */
63589 + else
63591 + if ((pAbrsLList = abr_entry->AbrsLList) == NULL)
63593 + patricia_tree_del (&ASBorderTree, &abr_entry->Node);
63594 + XFREE (MTYPE_TE, abr_entry);
63595 + XFREE (MTYPE_TE, pNew);
63596 + zlog_err ("\nFatal at %s %d", __FILE__, __LINE__);
63597 + return E_ERR;
63599 + /* Lookup for the ABR in ABR's Linked List */
63600 + pAbrsLListPrev = pAbrsLList;
63601 + while (pAbrsLList != NULL)
63603 + /* if summaries are equal */
63604 + if (pAbrsLList->Abr->AbrIpAddr == pAbr->AbrIpAddr)
63606 + /* free the unneeded memory */
63607 + delete_abr (pAbrsLList->Abr);
63608 + pAbrsLList->Abr = pAbr;
63609 + XFREE (MTYPE_TE, pNew);
63610 + return E_OK;
63611 + } /* if this is the ABR ? */
63612 + else if (pAbrsLList->Abr->AbrIpAddr > pAbr->AbrIpAddr)
63614 + /* insert to the head */
63615 + if (pAbrsLList == abr_entry->AbrsLList)
63617 + pNew->next = abr_entry->AbrsLList;
63618 + abr_entry->AbrsLList = pNew;
63620 + /* insert to the middle */
63621 + else
63623 + pAbrsLListPrev->next = pNew;
63624 + pNew->next = pAbrsLList;
63626 + abr_entry->LListItemsCount++;
63627 + return E_OK;
63629 + pAbrsLListPrev = pAbrsLList;
63630 + pAbrsLList = pAbrsLList->next;
63631 + } /* while pAbrsLList != NULL */
63633 + /* If this point is reached, ABR should be inserted to the ABR's list */
63634 + pAbrsLListPrev->next = pNew;
63635 + pNew->next = pAbrsLList;
63636 + abr_entry->LListItemsCount++;
63637 + return E_OK;
63641 +/*****************************************************************************
63643 + PROCEDURE NAME: rdb_delete_asbr
63645 + DESCRIPTION: When Area Border abr_ip does not longer advertise the reachability
63646 + information to AS border asbr_ip, the Area Border's summary to the AS border
63647 + is deleted.
63649 + PARAMETERS: rdb_handle - Routing Data Base handle.
63650 + asbr_ip - AS border's IP address.
63651 + abr_ip - Area border's IP address.
63653 +*****************************************************************************/
63654 +uns32
63655 +rdb_delete_asbr (IPV4_ADDR asbr_ip, IPV4_ADDR abr_ip)
63657 + RDB_ABRS *abr_entry;
63658 + ABRS_L_LIST *pAbrsLList, *pAbrsLListPrev = NULL;
63660 + if ((abr_entry = (RDB_ABRS *) patricia_tree_get (&ASBorderTree,
63661 + (const uns8 *) &asbr_ip))
63662 + == NULL)
63664 + return E_ERR;
63666 + else
63668 + pAbrsLList = abr_entry->AbrsLList;
63669 + while (pAbrsLList != NULL)
63671 + if (pAbrsLList->Abr->AbrIpAddr == abr_ip)
63673 + delete_abr (pAbrsLList->Abr);
63675 + if (abr_entry->AbrsLList == pAbrsLList)
63677 + abr_entry->AbrsLList = abr_entry->AbrsLList->next;
63678 + XFREE (MTYPE_TE, pAbrsLList);
63679 + abr_entry->LListItemsCount--;
63680 + if (abr_entry->AbrsLList == NULL)
63682 + if (patricia_tree_del (&ASBorderTree, &abr_entry->Node)
63683 + != E_OK)
63685 + return E_ERR;
63687 + XFREE (MTYPE_TE, abr_entry);
63690 + else
63692 + pAbrsLListPrev->next = pAbrsLList->next;
63693 + abr_entry->LListItemsCount--;
63694 + XFREE (MTYPE_TE, pAbrsLList);
63697 + return E_OK;
63699 + else
63701 + pAbrsLListPrev = pAbrsLList;
63702 + pAbrsLList = pAbrsLList->next;
63706 + return E_ERR;
63710 +/*****************************************************************************
63712 + PROCEDURE NAME: rdb_create_static_path
63714 + DESCRIPTION: Adds a new path *pPath to destination dest_ip.
63716 + PARAMETERS: rdb_handle - Routing Data Base handle.
63717 + dest_ip - Path destination's IP address.
63718 + *pPath - pointer to the path description (path's summary propertieslist of hops
63719 + and hops' properties).
63721 +*****************************************************************************/
63722 +uns32
63723 +rdb_create_static_path (char *StaticPathName)
63725 + STATIC_PATH *pStaticPath;
63727 + if (rdb_get_static_path (StaticPathName, &pStaticPath) == E_OK)
63729 + zlog_err ("Static path with the name %s already exists %s %d",
63730 + StaticPathName, __FILE__, __LINE__);
63731 + return E_ERR;
63734 + if ((pStaticPath =
63735 + (STATIC_PATH *) XMALLOC (MTYPE_TE, sizeof (STATIC_PATH))) == NULL)
63737 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
63738 + return E_ERR;
63740 + memset (pStaticPath, 0, sizeof (STATIC_PATH));
63741 + strcpy (pStaticPath->PathName, StaticPathName);
63743 + if (StaticPathHead == NULL)
63745 + StaticPathHead = pStaticPath;
63746 + StaticPathHead->next = NULL;
63748 + else
63750 + pStaticPath->next = StaticPathHead;
63751 + StaticPathHead = pStaticPath;
63753 + return E_OK;
63756 +/*****************************************************************************
63758 + PROCEDURE NAME: rdb_delete_static_path
63760 + DESCRIPTION: Adds a new path *pPath to destination dest_ip.
63762 + PARAMETERS: rdb_handle - Routing Data Base handle.
63763 + dest_ip - Path destination's IP address.
63764 + *pPath - pointer to the path description (path's summary propertieslist of hops
63765 + and hops' properties).
63767 +*****************************************************************************/
63768 +uns32
63769 +rdb_delete_static_path (char *StaticPathName)
63771 + IPV4_HOP *HopsList, *HopsListNext;
63772 + STATIC_PATH *pTemp = StaticPathHead, *pPrev = NULL;
63774 + while (pTemp != NULL)
63776 + if (strcmp (pTemp->PathName, StaticPathName) == 0)
63778 + HopsList = pTemp->HopList;
63779 + while (HopsList != NULL)
63781 + HopsListNext = HopsList->next;
63782 + XFREE (MTYPE_TE, HopsList);
63783 + HopsList = HopsListNext;
63785 + if (pPrev == NULL)
63787 + StaticPathHead = StaticPathHead->next;
63789 + else
63791 + pPrev->next = pTemp->next;
63793 + XFREE (MTYPE_TE, pTemp);
63794 + return E_OK;
63796 + pPrev = pTemp;
63797 + pTemp = pTemp->next;
63799 + return E_ERR;
63802 +/*****************************************************************************
63804 + PROCEDURE NAME: rdb_get_static_path
63806 + DESCRIPTION: Adds a new path *pPath to destination dest_ip.
63808 + PARAMETERS: rdb_handle - Routing Data Base handle.
63809 + dest_ip - Path destination's IP address.
63810 + *pPath - pointer to the path description (path's summary propertieslist of hops
63811 + and hops' properties).
63813 +*****************************************************************************/
63814 +uns32
63815 +rdb_get_static_path (char *pName, STATIC_PATH ** ppStaticPath)
63817 + if (StaticPathHead == NULL)
63819 + *ppStaticPath = NULL;
63821 + else
63823 + STATIC_PATH *pTemp = StaticPathHead;
63824 + while (pTemp != NULL)
63826 + if (strcmp (pTemp->PathName, pName) == 0)
63828 + *ppStaticPath = pTemp;
63829 + return E_OK;
63831 + pTemp = pTemp->next;
63834 + return E_ERR;
63837 +/*****************************************************************************
63839 + PROCEDURE NAME: rdb_static_path_add_hop
63841 + DESCRIPTION: Adds a new path *pPath to destination dest_ip.
63843 + PARAMETERS: rdb_handle - Routing Data Base handle.
63844 + dest_ip - Path destination's IP address.
63845 + *pPath - pointer to the path description (path's summary propertieslist of hops
63846 + and hops' properties).
63848 +*****************************************************************************/
63849 +uns32
63850 +rdb_static_path_add_hop (char *StaticPathName, IPV4_ADDR IpAddr, int Loose)
63852 + STATIC_PATH *pStaticPath;
63853 + IPV4_HOP *HopsList, *HopsListNew;
63855 + if (rdb_get_static_path (StaticPathName, &pStaticPath) != E_OK)
63857 + zlog_err ("Cannot find a path with name %s %s %d", StaticPathName,
63858 + __FILE__, __LINE__);
63859 + return E_ERR;
63861 + if ((HopsListNew =
63862 + (IPV4_HOP *) XMALLOC (MTYPE_TE, sizeof (IPV4_HOP))) == NULL)
63864 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
63865 + return E_ERR;
63867 + memset (HopsListNew, 0, sizeof (IPV4_HOP));
63868 + HopsListNew->IpAddr = IpAddr;
63869 + HopsListNew->Loose = Loose;
63870 + if (pStaticPath->HopList == NULL)
63872 + pStaticPath->HopList = HopsListNew;
63874 + else
63876 + HopsList = pStaticPath->HopList;
63877 + while (HopsList->next != NULL)
63878 + HopsList = HopsList->next;
63879 + HopsList->next = HopsListNew;
63881 + pStaticPath->HopCount++;
63882 + return E_OK;
63885 +/*****************************************************************************
63887 + PROCEDURE NAME: rdb_static_path_add_hop_by_index
63889 + DESCRIPTION: Adds a new path *pPath to destination dest_ip.
63891 + PARAMETERS: rdb_handle - Routing Data Base handle.
63892 + dest_ip - Path destination's IP address.
63893 + *pPath - pointer to the path description (path's summary propertieslist of hops
63894 + and hops' properties).
63896 +*****************************************************************************/
63897 +uns32
63898 +rdb_static_path_add_hop_by_index (char *StaticPathName, IPV4_ADDR IpAddr,
63899 + int Loose, int index)
63901 + STATIC_PATH *pStaticPath;
63902 + IPV4_HOP *HopsList, *HopsListNew, *HopsListPrev = NULL;
63903 + int i = 0;
63905 + if (index == 0)
63907 + zlog_err ("invalid parameter (index == 0) %s %d", __FILE__, __LINE__);
63908 + return E_ERR;
63910 + index--;
63911 + if (rdb_get_static_path (StaticPathName, &pStaticPath) != E_OK)
63913 + zlog_err ("Cannot find a path %s %d", __FILE__, __LINE__);
63914 + return E_ERR;
63916 + zlog_info ("Index %d", index);
63917 + HopsList = pStaticPath->HopList;
63918 + while ((HopsList != NULL) && (i < index))
63920 + HopsListPrev = HopsList;
63921 + HopsList = HopsList->next;
63922 + i++;
63924 + if (i != index)
63926 + zlog_err ("There is no such index %d %s %d", index, __FILE__, __LINE__);
63927 + return E_ERR;
63930 + if (HopsList)
63932 + HopsList->IpAddr = IpAddr;
63933 + HopsList->Loose = Loose;
63935 + else
63937 + if ((HopsListNew =
63938 + (IPV4_HOP *) XMALLOC (MTYPE_TE, sizeof (IPV4_HOP))) == NULL)
63940 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
63941 + return E_ERR;
63943 + memset (HopsListNew, 0, sizeof (IPV4_HOP));
63944 + HopsListNew->IpAddr = IpAddr;
63945 + HopsListNew->Loose = Loose;
63946 + if (HopsListPrev == NULL)
63948 + pStaticPath->HopList = HopsListNew;
63950 + else
63952 + HopsListPrev->next = HopsListNew;
63953 + HopsListNew = HopsList;
63955 + pStaticPath->HopCount++;
63957 + return E_OK;
63960 +/*****************************************************************************
63962 + PROCEDURE NAME: rdb_static_path_add_hop_after_index
63964 + DESCRIPTION: Adds a new path *pPath to destination dest_ip.
63966 + PARAMETERS: rdb_handle - Routing Data Base handle.
63967 + dest_ip - Path destination's IP address.
63968 + *pPath - pointer to the path description (path's summary propertieslist of hops
63969 + and hops' properties).
63971 +*****************************************************************************/
63972 +uns32
63973 +rdb_static_path_add_hop_after_index (char *StaticPathName, IPV4_ADDR IpAddr,
63974 + int Loose, int index)
63976 + STATIC_PATH *pStaticPath;
63977 + IPV4_HOP *HopsList, *HopsListNew, *HopsListPrev = NULL;
63978 + int i = 0;
63980 + if (index == 0)
63982 + zlog_err ("invalid parameter (index == 0) %s %d", __FILE__, __LINE__);
63983 + return E_ERR;
63985 + zlog_info ("Index %d", index);
63986 + if (rdb_get_static_path (StaticPathName, &pStaticPath) != E_OK)
63988 + zlog_err ("Cannot find a path %s %d", __FILE__, __LINE__);
63989 + return E_ERR;
63992 + HopsList = pStaticPath->HopList;
63993 + while ((HopsList != NULL) && (i < index))
63995 + HopsListPrev = HopsList;
63996 + HopsList = HopsList->next;
63997 + i++;
63999 + if (i != index)
64001 + zlog_err ("There is no such index %d %s %d", index, __FILE__, __LINE__);
64002 + return E_ERR;
64005 + if ((HopsListNew =
64006 + (IPV4_HOP *) XMALLOC (MTYPE_TE, sizeof (IPV4_HOP))) == NULL)
64008 + zlog_err ("Cannot allocate memory %s %d", __FILE__, __LINE__);
64009 + return E_ERR;
64011 + memset (HopsListNew, 0, sizeof (IPV4_HOP));
64012 + HopsListNew->IpAddr = IpAddr;
64013 + HopsListNew->Loose = Loose;
64014 + HopsListPrev->next = HopsListNew;
64015 + HopsListNew->next = HopsList;
64016 + pStaticPath->HopCount++;
64017 + return E_OK;
64020 +/*****************************************************************************
64022 + PROCEDURE NAME: rdb_static_path_del_hop
64024 + DESCRIPTION: Adds a new path *pPath to destination dest_ip.
64026 + PARAMETERS: rdb_handle - Routing Data Base handle.
64027 + dest_ip - Path destination's IP address.
64028 + *pPath - pointer to the path description (path's summary propertieslist of hops
64029 + and hops' properties).
64031 +*****************************************************************************/
64032 +uns32
64033 +rdb_static_path_del_hop (char *StaticPathName, IPV4_ADDR IpAddr)
64035 + STATIC_PATH *pStaticPath;
64036 + IPV4_HOP *HopsList, *HopsListPrev = NULL;
64038 + if (rdb_get_static_path (StaticPathName, &pStaticPath) != E_OK)
64040 + zlog_err ("Cannot find a path %s %d", __FILE__, __LINE__);
64041 + return E_ERR;
64043 + HopsList = pStaticPath->HopList;
64044 + while (HopsList != NULL)
64046 + if (HopsList->IpAddr == IpAddr)
64047 + break;
64048 + HopsListPrev = HopsList;
64049 + HopsList = HopsList->next;
64052 + if (HopsList == NULL)
64054 + zlog_err ("Hop %x is not found %s %d", IpAddr, __FILE__, __LINE__);
64055 + return E_ERR;
64058 + if (HopsListPrev == NULL)
64060 + pStaticPath->HopList = pStaticPath->HopList->next;
64062 + else
64064 + HopsListPrev->next = HopsList->next;
64066 + XFREE (MTYPE_TE, HopsList);
64067 + pStaticPath->HopCount--;
64068 + return E_OK;
64071 +/*****************************************************************************
64073 + PROCEDURE NAME: rdb_static_path_del_hop_by_index
64075 + DESCRIPTION: Adds a new path *pPath to destination dest_ip.
64077 + PARAMETERS: rdb_handle - Routing Data Base handle.
64078 + dest_ip - Path destination's IP address.
64079 + *pPath - pointer to the path description (path's summary propertieslist of hops
64080 + and hops' properties).
64082 +*****************************************************************************/
64083 +uns32
64084 +rdb_static_path_del_hop_by_index (char *StaticPathName, int index)
64086 + STATIC_PATH *pStaticPath;
64087 + IPV4_HOP *HopsList, *HopsListPrev = NULL;
64088 + int i = 0;
64090 + if (index == 0)
64092 + zlog_err ("invalid parameter (index == 0) %s %d", __FILE__, __LINE__);
64093 + return E_ERR;
64095 + index--;
64096 + if (rdb_get_static_path (StaticPathName, &pStaticPath) != E_OK)
64098 + zlog_err ("Cannot find a path %s %d", __FILE__, __LINE__);
64099 + return E_ERR;
64101 + zlog_info ("Index %d", index);
64102 + HopsList = pStaticPath->HopList;
64103 + while ((HopsList != NULL) && (i < index))
64105 + HopsListPrev = HopsList;
64106 + HopsList = HopsList->next;
64107 + i++;
64109 + if (i != index)
64111 + zlog_err ("There is no such index %d %s %d", index, __FILE__, __LINE__);
64112 + return E_ERR;
64114 + if (HopsListPrev == NULL)
64116 + pStaticPath->HopList = pStaticPath->HopList->next;
64118 + else
64120 + HopsListPrev->next = HopsList->next;
64122 + XFREE (MTYPE_TE, HopsList);
64123 + pStaticPath->HopCount--;
64124 + return E_OK;
64127 +/*****************************************************************************
64129 + PROCEDURE NAME: rdb_add_mod_path
64131 + DESCRIPTION: Adds a new path *pPath to destination dest_ip.
64133 + PARAMETERS: rdb_handle - Routing Data Base handle.
64134 + dest_ip - Path destination's IP address.
64135 + *pPath - pointer to the path description (path's summary propertieslist of hops
64136 + and hops' properties).
64138 +*****************************************************************************/
64139 +uns32
64140 +rdb_add_mod_path (IPV4_ADDR dest_ip, PATH * pPath)
64142 + RDB_PATH *path_entry;
64143 + PATH_L_LIST *pPathLList, *pPathLListPrev, *pErHopPathList;
64145 + PATH_L_LIST *pNewPath;
64146 + TE_HOP *pKxErHop;
64147 + ER_HOP_L_LIST *pKxErHopsLList;
64148 + TE_HOP *pErHops, *pErHops2Free;
64149 + link_key_t link_key;
64150 + int i, j;
64153 + if ((pPath->PathProperties.PathType <= EMPTY_PATH)
64154 + || (pPath->PathProperties.PathType >= MAX_PATH_TYPE))
64156 + zlog_err ("Invalid path type %d", pPath->PathProperties.PathType);
64157 + return E_ERR;
64160 + if ((pNewPath =
64161 + (PATH_L_LIST *) XMALLOC (MTYPE_TE, sizeof (PATH_L_LIST))) == NULL)
64163 + XFREE (MTYPE_TE, pPath->u.er_hops);
64164 + XFREE (MTYPE_TE, pPath);
64165 + zlog_err ("malloc failed %s %d", __FILE__, __LINE__);
64166 + return E_ERR;
64168 + pNewPath->pPath = pPath;
64169 + pNewPath->next = NULL;
64171 + if ((path_entry =
64172 + (RDB_PATH *) patricia_tree_get (&AreaBorderTree,
64173 + (const uns8 *) &dest_ip)) == NULL)
64175 + if ((path_entry =
64176 + (RDB_PATH *) XMALLOC (MTYPE_TE, sizeof (RDB_PATH))) == NULL)
64178 + XFREE (MTYPE_TE, pNewPath);
64179 + zlog_err ("malloc failed %s %d", __FILE__, __LINE__);
64180 + return E_ERR;
64182 + /* Initialize new ABR */
64183 + path_entry->dest = dest_ip;
64184 + path_entry->Node.key_info = (uns8 *) & path_entry->dest;
64185 + path_entry->PathLList = pNewPath;
64187 + path_entry->LListItemsCount = 1;
64189 + if (patricia_tree_add (&AreaBorderTree, &path_entry->Node) != E_OK)
64191 + XFREE (MTYPE_TE, path_entry);
64192 + XFREE (MTYPE_TE, pNewPath);
64193 + XFREE (MTYPE_TE, pPath->u.er_hops);
64194 + XFREE (MTYPE_TE, pPath);
64195 + zlog_err ("cannot add node to patricia %s %d", __FILE__, __LINE__);
64196 + return E_ERR;
64199 + /* There is no such ABR */
64200 + else
64202 + /* Initialize new Path to ABR */
64203 + if ((pPathLList = path_entry->PathLList) == NULL)
64205 + patricia_tree_del (&AreaBorderTree, &path_entry->Node);
64206 + XFREE (MTYPE_TE, path_entry);
64207 + XFREE (MTYPE_TE, pNewPath);
64208 + XFREE (MTYPE_TE, pPath->u.er_hops);
64209 + XFREE (MTYPE_TE, pPath);
64210 + zlog_err ("Fatal at %s %d", __FILE__, __LINE__);
64211 + return E_ERR;
64213 + /* Lookup for the Path in Path's Linked List */
64214 + pPathLListPrev = pPathLList;
64215 + while (pPathLList != NULL)
64217 + /* if path vectors are equal */
64218 + if ((pPathLList->pPath->PathProperties.PathType ==
64219 + pPath->PathProperties.PathType)
64220 + && (pPathLList->pPath->PathProperties.PathHopCount ==
64221 + pPath->PathProperties.PathHopCount)
64222 + &&
64223 + (compare_er_hops
64224 + (pPathLList->pPath->u.er_hops_l_list, pPath->u.er_hops,
64225 + pPath->PathProperties.PathHopCount) == TRUE))
64227 + /* if path properties are equal, nothing to do */
64228 + memcpy (&pPathLList->pPath->PathProperties,
64229 + &pPath->PathProperties, sizeof (PATH_PROPERTIES));
64231 + pErHops = pPath->u.er_hops;
64233 + for (i = 0; i < pPath->PathProperties.PathHopCount;
64234 + i++, pErHops++)
64236 + LINK_PROPERTIES link_prop;
64238 + memset (&link_prop, 0, sizeof (link_prop));
64240 + link_prop.LinkType = PSC_PATH;
64241 + link_prop.LinkMaxLspBW = pErHops->MaxLspBW;
64242 + link_prop.LinkMaxReservableBW = pErHops->MaxReservableBW;
64243 + link_prop.LinkTeMetric = pErHops->te_metric;
64244 + for (j = 0; j < 8; j++)
64246 + link_prop.LinkReservableBW[j] =
64247 + pErHops->ReservableBW[j];
64249 + link_prop.LinkColorMask = pErHops->ColorMask;
64250 + rdb_link_state_update (pErHops->local_ip,
64251 + pErHops->remote_ip, &link_prop);
64253 + XFREE (MTYPE_TE, pPath->u.er_hops);
64254 + XFREE (MTYPE_TE, pPath);
64255 + XFREE (MTYPE_TE, pNewPath);
64256 + zlog_info ("paths are equal %s %d", __FILE__, __LINE__);
64257 + return E_OK;
64258 + } /* if er hops equal */
64259 + pPathLListPrev = pPathLList;
64260 + pPathLList = pPathLList->next;
64261 + } /* while */
64263 + /* If this point is reached, path should be inserted to the path list */
64264 + /* insert to the head */
64265 + pNewPath->next = path_entry->PathLList;
64266 + path_entry->PathLList = pNewPath;
64267 + path_entry->LListItemsCount++;
64268 + } /* ABR already exists */
64270 + /* now, check for existence of links to remote links and set if required */
64271 + pErHops2Free = pPath->u.er_hops; /* to free after the loop */
64273 + pErHops = pPath->u.er_hops;
64275 + pNewPath->pPath->u.er_hops_l_list = pKxErHopsLList = NULL;
64277 + for (i = 0; i < pPath->PathProperties.PathHopCount; i++, pErHops++)
64279 + link_key.local_ip = pErHops->local_ip;
64280 + link_key.remote_ip = pErHops->remote_ip;
64282 + if ((pErHopPathList =
64283 + (PATH_L_LIST *) XMALLOC (MTYPE_TE, sizeof (PATH_L_LIST))) == NULL)
64285 + zlog_err ("malloc failed %s %d", __FILE__, __LINE__);
64286 + return E_ERR;
64288 + pErHopPathList->pPath = pPath;
64290 + if ((pKxErHop =
64291 + (TE_HOP *)
64292 + patricia_tree_get (&
64293 + (RemoteLinkTree
64294 + [pPath->PathProperties.PathType - 1]),
64295 + (const uns8 *) &link_key)) == NULL)
64297 + if ((pKxErHop =
64298 + (TE_HOP *) XMALLOC (MTYPE_TE, sizeof (TE_HOP))) == NULL)
64300 + zlog_err ("malloc failed %s %d", __FILE__, __LINE__);
64301 + return E_ERR;
64304 + pKxErHop->pPathList = pErHopPathList;
64305 + pKxErHop->pPathList->next = NULL;
64306 + pKxErHop->local_ip = link_key.local_ip;
64307 + pKxErHop->remote_ip = link_key.remote_ip;
64308 + pKxErHop->MaxLspBW = pErHops->MaxLspBW;
64309 + pKxErHop->MaxReservableBW = pErHops->MaxReservableBW;
64310 + for (j = 0; j < 8; j++)
64311 + pKxErHop->ReservableBW[j] = pErHops->ReservableBW[j];
64312 + pKxErHop->te_metric = pErHops->te_metric;
64313 + pKxErHop->ColorMask = pErHops->ColorMask;
64315 + pKxErHop->Node.key_info = (uns8 *) & pKxErHop->local_ip;
64316 + zlog_info
64317 + ("Creation of new remote link: local %x remote %x MaxBw %f MaxResBw %f %x",
64318 + pKxErHop->local_ip, pKxErHop->remote_ip, pKxErHop->MaxLspBW,
64319 + pKxErHop->MaxReservableBW, pKxErHop->te_metric);
64320 + if (patricia_tree_add
64321 + (&(RemoteLinkTree[pPath->PathProperties.PathType - 1]),
64322 + &pKxErHop->Node) != E_OK)
64324 + zlog_err ("cannot add node to patricia %s %d", __FILE__,
64325 + __LINE__);
64326 + return E_ERR;
64329 + else
64331 + pErHopPathList->next = pKxErHop->pPathList;
64332 + pKxErHop->pPathList = pErHopPathList;
64335 + if (pNewPath->pPath->u.er_hops_l_list == NULL)
64337 + if ((pKxErHopsLList =
64338 + (ER_HOP_L_LIST *) XMALLOC (MTYPE_TE,
64339 + sizeof (ER_HOP_L_LIST))) == NULL)
64341 + zlog_err ("malloc failed %s %d", __FILE__, __LINE__);
64342 + return E_ERR;
64344 + pNewPath->pPath->u.er_hops_l_list = pKxErHopsLList;
64346 + else
64348 + if ((pKxErHopsLList->next =
64349 + (ER_HOP_L_LIST *) XMALLOC (MTYPE_TE,
64350 + sizeof (ER_HOP_L_LIST))) == NULL)
64352 + zlog_err ("malloc failed %s %d", __FILE__, __LINE__);
64353 + return E_ERR;
64355 + pKxErHopsLList = pKxErHopsLList->next;
64358 + pKxErHopsLList->next = NULL;
64360 + pKxErHopsLList->er_hop = pKxErHop;
64363 + XFREE (MTYPE_TE, pErHops2Free);
64365 + return E_OK;
64368 +/*****************************************************************************
64370 + PROCEDURE NAME: rdb_connectivity_broken
64372 + DESCRIPTION: When IGP receives a Link Advertisement (LSA or LSP), which says there is no
64373 + connectivity from the node from_node to the node to_node for path type path_type (packet switch,
64374 + lambda switch, fiber switch, TDM switch), such path is deleted.
64376 + PARAMETERS: rdb_handle - Routing Data Base handle.
64377 + from_node - IP address of the node, from which connectivity is broken.
64378 + to_node - IP address of the node, to which connectivity is broken.
64379 + path_type - connectivity of which type is broken.
64381 + IMPORTANT NOTE: This API is not intended for indication of own link failures.
64383 +*****************************************************************************/
64385 +uns32
64386 +rdb_connectivity_broken (IPV4_ADDR from_node, IPV4_ADDR to_node,
64387 + PATH_TYPE path_type)
64389 + RDB_PATH *path_entry;
64390 + TE_HOP *pKxErHop;
64391 + link_key_t link_key;
64392 + PATH *pPath, *pSavedPath;
64394 + if ((path_type <= EMPTY_PATH) || (path_type >= MAX_PATH_TYPE))
64395 + return E_ERR;
64396 + link_key.local_ip = from_node;
64397 + link_key.remote_ip = to_node;
64399 + /* first, find the remote link */
64400 + if ((pKxErHop =
64401 + (TE_HOP *) patricia_tree_get (&(RemoteLinkTree[path_type - 1]),
64402 + (const uns8 *) &link_key)) != NULL)
64404 + PATH_L_LIST *pPathList, *pPathListNext, *pPathList2, *pPathListPrev2;
64405 + zlog_info ("connectivity broken event upon reception of TE LSA: %x %x",
64406 + from_node, to_node);
64407 + pPathList = pKxErHop->pPathList;
64408 + /* for each path, passing through this remote link */
64409 + while (pPathList != NULL)
64411 + pPathListNext = pPathList->next;
64412 + pSavedPath = pPathList->pPath;
64413 + /* find path's destination */
64414 + zlog_info ("Path's destination %x", pPathList->pPath->destination);
64415 + if ((path_entry = (RDB_PATH *) patricia_tree_get (&AreaBorderTree,
64416 + (const uns8 *)
64417 + &pPathList->
64418 + pPath->
64419 + destination)) !=
64420 + NULL)
64422 + zlog_info
64423 + ("Delete path from the list, hold by destination entry");
64424 + pPathListPrev2 = pPathList2 = path_entry->PathLList;
64425 + /* find the path in the path destination's path list */
64426 + while (pPathList2 != NULL)
64428 + /* path is found ? */
64429 + if (pPathList2->pPath == pPathList->pPath)
64431 + zlog_info ("path found on the destination's list ...");
64432 + /* extract the path from the path destination's path list
64433 + without freing the memory */
64434 + if (pPathList2 == pPathListPrev2)
64435 + path_entry->PathLList = path_entry->PathLList->next;
64436 + else
64437 + pPathListPrev2->next = pPathList2->next;
64439 + path_entry->LListItemsCount--;
64440 + /* if ocausionally, path destination's path list became empty,
64441 + delete the destination from the patricia tree
64442 + and free the destination's memory */
64443 + if (path_entry->PathLList == NULL)
64445 + patricia_tree_del (&AreaBorderTree,
64446 + &path_entry->Node);
64447 + XFREE (MTYPE_TE, path_entry);
64449 + /* free the destination's path list item memory */
64450 + XFREE (MTYPE_TE, pPathList2);
64451 + break;
64452 + } /* path found on the path's destination's path list */
64453 + pPathListPrev2 = pPathList2;
64454 + pPathList2 = pPathList2->next;
64455 + } /* of while (through the path list of path's destination */
64457 + /* now, the memory of the remote link's path list item and
64458 + path's itself memory remain. Check if path references remote links,
64459 + which are referenced by this path only. If such links are discovered,
64460 + remove them. */
64461 + zlog_info ("now, delete the path from the lists, hold by TE links");
64463 + pPath = pPathList->pPath;
64464 + while (pPath->u.er_hops_l_list != NULL)
64466 + ER_HOP_L_LIST *pTemp = pPath->u.er_hops_l_list->next;
64467 + if (pPath->u.er_hops_l_list->er_hop != NULL)
64469 + pPathListPrev2 = pPathList2 =
64470 + pPath->u.er_hops_l_list->er_hop->pPathList;
64471 + while (pPathList2 != NULL)
64473 + if (pPathList2->pPath == pPath)
64475 + if (pPathListPrev2 == pPathList2)
64477 + pPath->u.er_hops_l_list->er_hop->pPathList =
64478 + pPath->u.er_hops_l_list->er_hop->pPathList->
64479 + next;
64481 + else
64483 + pPathListPrev2->next = pPathList2->next;
64485 + XFREE (MTYPE_TE, pPathList2);
64486 + break;
64488 + pPathListPrev2 = pPathList2;
64489 + pPathList2 = pPathList2->next;
64492 + if (pPath->u.er_hops_l_list->er_hop->pPathList == NULL)
64494 + zlog_info
64495 + ("All paths, passed through the TE link are removed from the path list of this TE link %x %x",
64496 + pPath->u.er_hops_l_list->er_hop->local_ip,
64497 + pPath->u.er_hops_l_list->er_hop->remote_ip);
64498 + patricia_tree_del (&(RemoteLinkTree[0]),
64499 + &pPath->u.er_hops_l_list->er_hop->Node);
64500 + XFREE (MTYPE_TE, pPath->u.er_hops_l_list->er_hop);
64502 + XFREE (MTYPE_TE, pPath->u.er_hops_l_list);
64503 + pPath->u.er_hops_l_list = pTemp;
64507 + zlog_info ("all er hop list items cleaned. delete the path");
64509 + XFREE (MTYPE_TE, pSavedPath);
64511 + pPathList = pPathListNext;
64514 + return E_OK;
64517 +/*****************************************************************************
64519 + PROCEDURE NAME: rdb_link_state_update
64521 + DESCRIPTION: When IGP receives a Link Advertisement (LSA or LSP), which says that TE link properties
64522 + are updated, this routine is called to update paths' properties for each path, pass the pair
64523 + from_node->to_node.
64525 + PARAMETERS: rdb_handle - Routing Data Base handle.
64526 + from_node - Local IP address of the TE link.
64527 + to_node - Remote IP address of the TE link.
64528 + path_type - TE link type (there may be TE links of different packet switch capacity between
64529 + the two nodes).
64531 + IMPORTANT NOTE: The IGP instance may aggregate the two or more TE links between the same nodes as well
64532 + as some node aggregates the component links into one TE link. The conditions are: same IGP and TE
64533 + costs of the TE links.
64534 + This routine is for Link State Updates of remote links only.
64536 +*****************************************************************************/
64538 +uns32
64539 +rdb_link_state_update (IPV4_ADDR from_node, IPV4_ADDR to_node,
64540 + LINK_PROPERTIES * pLinkProperties)
64542 + TE_HOP *pKxErHop;
64543 + link_key_t link_key;
64544 + int i, recalculate = 0;
64545 + float PathReservableBW[8], PathMaxLspBW, PathMaxReservableBW, delta;
64546 + int ColorMask, j;
64548 + if ((pLinkProperties->LinkType <= EMPTY_PATH)
64549 + || (pLinkProperties->LinkType >= MAX_PATH_TYPE))
64550 + return E_ERR;
64551 + link_key.local_ip = from_node;
64552 + link_key.remote_ip = to_node;
64554 + /* first, find the remote link */
64555 + if ((pKxErHop =
64556 + (TE_HOP *)
64557 + patricia_tree_get (&(RemoteLinkTree[pLinkProperties->LinkType - 1]),
64558 + (const uns8 *) &link_key)) != NULL)
64560 + PATH_L_LIST *pPathList;
64562 + pPathList = pKxErHop->pPathList;
64563 + zlog_info ("Path Cash update upon updated TE LSA %x %x", from_node,
64564 + to_node);
64565 + /* for each path, passes over this remote link */
64566 + while (pPathList != NULL)
64568 + PATH *pPath;
64569 + PATH_PROPERTIES *pProperties = &(pPathList->pPath->PathProperties);
64570 + ER_HOP_L_LIST *pErHopLList;
64572 + recalculate = 0;
64574 + if (pLinkProperties->LinkMaxLspBW <= pProperties->PathMaxLspBW)
64575 + pProperties->PathMaxLspBW = pLinkProperties->LinkMaxLspBW;
64576 + else
64577 + recalculate = 1;
64579 + if (pLinkProperties->LinkMaxReservableBW <=
64580 + pProperties->PathMaxReservableBW)
64581 + pProperties->PathMaxReservableBW =
64582 + pLinkProperties->LinkMaxReservableBW;
64583 + else
64584 + recalculate = 1;
64586 + for (j = 0; j < 8; j++)
64588 + if (pLinkProperties->LinkReservableBW[j] <=
64589 + pProperties->PathReservableBW[j])
64590 + pProperties->PathReservableBW[j] =
64591 + pLinkProperties->LinkReservableBW[j];
64592 + else
64594 + recalculate = 1;
64595 + break;
64599 + if (pKxErHop->ColorMask != pLinkProperties->LinkColorMask)
64600 + recalculate = 1;
64602 + delta = pKxErHop->te_metric - pLinkProperties->LinkTeMetric;
64603 + pProperties->PathSumTeMetric -= delta;
64605 + pPath = pPathList->pPath;
64606 + pErHopLList = pPath->u.er_hops_l_list;
64608 + if (recalculate)
64610 + for (j = 0; j < 8; j++)
64611 + PathReservableBW[j] = pLinkProperties->LinkReservableBW[j];
64612 + PathMaxLspBW = pLinkProperties->LinkMaxLspBW;
64613 + PathMaxReservableBW = pLinkProperties->LinkMaxReservableBW;
64614 + ColorMask = pLinkProperties->LinkColorMask;
64615 + for (i = 0; i < pPath->PathProperties.PathHopCount; i++)
64617 + if (pErHopLList->er_hop != pKxErHop)
64619 + if (pErHopLList->er_hop->MaxLspBW < PathMaxLspBW)
64620 + PathMaxLspBW = pErHopLList->er_hop->MaxLspBW;
64621 + if (pErHopLList->er_hop->MaxReservableBW <
64622 + PathMaxReservableBW)
64623 + PathMaxReservableBW =
64624 + pErHopLList->er_hop->MaxReservableBW;
64625 + for (j = 0; j < 8; j++)
64626 + if (pErHopLList->er_hop->ReservableBW[j] <
64627 + PathReservableBW[j])
64628 + PathReservableBW[j] =
64629 + pErHopLList->er_hop->ReservableBW[j];
64630 + ColorMask |= pErHopLList->er_hop->ColorMask;
64632 + pErHopLList = pErHopLList->next;
64634 + pProperties->PathColorMask = ColorMask;
64635 + pProperties->PathMaxLspBW = PathMaxLspBW;
64636 + pProperties->PathMaxReservableBW = PathMaxReservableBW;
64637 + for (j = 0; j < 8; j++)
64638 + pProperties->PathReservableBW[j] = PathReservableBW[j];
64641 + pPathList = pPathList->next;
64644 + pKxErHop->ColorMask = pLinkProperties->LinkColorMask;
64645 + pKxErHop->MaxLspBW = pLinkProperties->LinkMaxLspBW;
64646 + pKxErHop->MaxReservableBW = pLinkProperties->LinkMaxReservableBW;
64647 + for (j = 0; j < 8; j++)
64648 + pKxErHop->ReservableBW[j] = pLinkProperties->LinkReservableBW[j];
64649 + pKxErHop->te_metric = pLinkProperties->LinkTeMetric;
64651 + else
64653 +// zlog_info("Link %x %x is not in the TE DB",from_node,to_node);
64655 + return E_OK;
64658 +/*****************************************************************************
64660 + PROCEDURE NAME: rdb_remote_link_bw_update
64662 + DESCRIPTION: When new RSVP LSP is created, if BW is expected to be allocated (according to rules - RSVP styles),
64663 + this routine must be called to maintain the path cash.
64665 + PARAMETERS: rdb_handle - Routing Data Base handle.
64666 + from_node - Local IP address of the TE link.
64667 + to_node - Remote IP address of the TE link.
64668 + BW2Decrease - BW to be subtrackted from the remote link's reservable BW.
64669 + LinkSwitchCap - link's switching capability.
64671 + IMPORTANT NOTE: This routine should be called on the case when BW is to be decreased only and
64672 + not in the case, when BW is to be increased - we wait for IGP's update.
64674 +*****************************************************************************/
64676 +uns32
64677 +rdb_remote_link_bw_update (IPV4_ADDR from_node,
64678 + IPV4_ADDR to_node,
64679 + float BW2Decrease,
64680 + uns8 Priority, PATH_TYPE LinkSwitchCap)
64682 + TE_HOP *pKxErHop;
64683 + link_key_t link_key;
64684 + int i, recalculate = 0;
64685 + float PathMaxReservableBW, HopMaxReservableBW;
64687 + link_key.local_ip = from_node;
64688 + link_key.remote_ip = to_node;
64690 + /* first, find the remote link */
64691 + if ((pKxErHop =
64692 + (TE_HOP *) patricia_tree_get (&(RemoteLinkTree[LinkSwitchCap - 1]),
64693 + (const uns8 *) &link_key)) != NULL)
64695 + PATH_L_LIST *pPathList;
64697 + pPathList = pKxErHop->pPathList;
64699 + if ((BW2Decrease > pKxErHop->ReservableBW[Priority]) ||
64700 + (BW2Decrease > pKxErHop->MaxLspBW))
64702 + zlog_err
64703 + ("\nBW to decrease is larger than MaxLspBW or Reservable BW %s %d",
64704 + __FILE__, __LINE__);
64705 + return E_ERR;
64707 + for (i = Priority; i < 8; i++)
64709 + if (pKxErHop->ReservableBW[i] >= BW2Decrease)
64711 + /*zlog_info("\nDecreasing %x BW from %x %x with %x BW",BW2Decrease,pKxErHop->local_ip,pKxErHop->remote_ip,pKxErHop->ReservableBW[i]); */
64712 + pKxErHop->ReservableBW[i] -= BW2Decrease; /* what with MaxLspBW ? -:) */
64714 + else
64715 + pKxErHop->ReservableBW[i] = 0;
64717 + HopMaxReservableBW = 0;
64718 + for (i = 0; i < 8; i++)
64720 + if (pKxErHop->ReservableBW[i] > HopMaxReservableBW)
64721 + HopMaxReservableBW = pKxErHop->ReservableBW[i];
64723 + pKxErHop->MaxReservableBW = HopMaxReservableBW;
64726 +#if 0
64727 + REMOTE_BW_UPDATE_REQUEST *pRemoteBwUpdateReq;
64728 + struct zapi_te_remote_link link;
64729 + memset(&link, 0, sizeof(struct zapi_te_remote_link));
64731 + rdb_remote_link_router_id_get (pKxErHop->local_ip,
64732 + &link.routerid.s_addr);
64733 + link.from_node.s_addr = pKxErHop->local_ip;
64734 + link.to_node.s_addr = pKxErHop->remote_ip;
64735 + for (i = 0; i < 8; i++)
64736 + link.reservable_bw[i] = pKxErHop->ReservableBW[i];
64737 + zapi_te_remote_link_update(zclient, &link);
64738 +#endif
64741 + /* for each path, passes over this remote link */
64742 + while (pPathList != NULL)
64744 + PATH_PROPERTIES *pProperties = &(pPathList->pPath->PathProperties);
64745 + recalculate = 0;
64747 + if (BW2Decrease > pProperties->PathReservableBW[Priority])
64749 + zlog_info
64750 + ("\nBW to decrease is larger than MaxLspBW or Reservable BW %s %d",
64751 + __FILE__, __LINE__);
64752 + pPathList = pPathList->next;
64753 + continue;
64755 + for (i = Priority; i < 8; i++)
64757 + if (pKxErHop->ReservableBW[i] <
64758 + pProperties->PathReservableBW[i])
64760 + /*zlog_info("\nForcing path BW to %x (prev - %x BW) Path's dest %x",pKxErHop->ReservableBW[i],pProperties->PathReservableBW[i],pPathList->pPath->destination); */
64761 + pProperties->PathReservableBW[i] =
64762 + pKxErHop->ReservableBW[i];
64765 + PathMaxReservableBW = 0;
64766 + for (i = 0; i < 8; i++)
64768 + if (pProperties->PathReservableBW[i] > PathMaxReservableBW)
64769 + PathMaxReservableBW = pProperties->PathReservableBW[i];
64771 + pProperties->PathMaxReservableBW = PathMaxReservableBW;
64772 + pPathList = pPathList->next;
64775 + else
64777 + zlog_err
64778 + ("\nSomething wrong - expected remote link %x %x is not found %s %d",
64779 + from_node, to_node, __FILE__, __LINE__);
64781 + return E_OK;
64784 +/*****************************************************************************
64786 + PROCEDURE NAME: rdb_remote_link_2_router_id_mapping
64788 + DESCRIPTION: This function is called to map a link to the router ID.
64790 + PARAMETERS: rdb_handle - Routing Data Base handle.
64791 + link_id - Local IP address of the TE link.
64792 + router_id - Router ID, to which this link belongs.
64794 +*****************************************************************************/
64796 +uns32
64797 +rdb_remote_link_2_router_id_mapping (IPV4_ADDR link_id, IPV4_ADDR router_id)
64799 + LINK_2_ROUTER_ID *pLink2RouterId;
64801 + if ((pLink2RouterId =
64802 + (LINK_2_ROUTER_ID *) patricia_tree_get (&Link2RouterIdTree,
64803 + (const uns8 *) &link_id)) ==
64804 + NULL)
64806 + if ((pLink2RouterId =
64807 + (LINK_2_ROUTER_ID *) XMALLOC (MTYPE_TE,
64808 + sizeof (LINK_2_ROUTER_ID))) == NULL)
64810 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
64811 + return E_ERR;
64813 + pLink2RouterId->link_id = link_id;
64814 + pLink2RouterId->router_id = router_id;
64815 + pLink2RouterId->Node.key_info = (uns8 *) & pLink2RouterId->link_id;
64816 + if (patricia_tree_add (&Link2RouterIdTree, &pLink2RouterId->Node) !=
64817 + E_OK)
64819 + zlog_err ("\ncannot add node to patricia %s %d...", __FILE__,
64820 + __LINE__);
64821 + return E_ERR;
64824 + else
64826 + pLink2RouterId->router_id = router_id;
64828 + return E_OK;
64831 +/*****************************************************************************
64833 + PROCEDURE NAME: rdb_remote_link_2_router_id_mapping_withdraw
64835 + DESCRIPTION: This function is called to remove a mapping of the link to the router ID.
64837 + PARAMETERS: rdb_handle - Routing Data Base handle.
64838 + link_id - Local IP address of the TE link.
64839 + router_id - Router ID, to which this link belongs.
64841 +*****************************************************************************/
64843 +uns32
64844 +rdb_remote_link_2_router_id_mapping_withdraw (IPV4_ADDR link_id)
64846 + LINK_2_ROUTER_ID *pLink2RouterId;
64848 + if ((pLink2RouterId =
64849 + (LINK_2_ROUTER_ID *) patricia_tree_get (&Link2RouterIdTree,
64850 + (const uns8 *) &link_id)) !=
64851 + NULL)
64853 + if (patricia_tree_del (&Link2RouterIdTree, &pLink2RouterId->Node) !=
64854 + E_OK)
64856 + zlog_err ("\ncannot add node to patricia %s %d...", __FILE__,
64857 + __LINE__);
64858 + return E_ERR;
64861 + return E_OK;
64864 +uns32
64865 +rdb_set_router_id (IPV4_ADDR IpAddr)
64867 + RouterID = IpAddr;
64868 + return E_OK;
64871 +IPV4_ADDR
64872 +rdb_get_router_id ()
64874 + return RouterID;
64877 +/*****************************************************************************
64879 + PROCEDURE NAME: rdb_remote_link_router_id_get
64881 + DESCRIPTION: This function is called to determine that link belongs to certain router.
64883 + PARAMETERS: rdb_handle - Routing Data Base handle.
64884 + from_node - Local IP address of the TE link.
64885 + router_id - Router ID, to which this link belongs.
64887 +*****************************************************************************/
64889 +uns32
64890 +rdb_remote_link_router_id_get (IPV4_ADDR from_node, IPV4_ADDR * router_id)
64892 + LINK_2_ROUTER_ID *pLink2RouterId;
64894 + /* first, find the remote link */
64895 + if ((pLink2RouterId =
64896 + (LINK_2_ROUTER_ID *) patricia_tree_get (&Link2RouterIdTree,
64897 + (const uns8 *) &from_node)) !=
64898 + NULL)
64900 + *router_id = pLink2RouterId->router_id;
64901 + return E_OK;
64903 + return E_ERR;
64906 +/*****************************************************************************
64908 + PROCEDURE NAME: rdb_igp_hello
64910 + DESCRIPTION: This function is called upon reception of Hello message from IGP in order to update it with already existing allocations.
64912 + PARAMETERS:
64914 +*****************************************************************************/
64916 +uns32
64917 +rdb_igp_hello ()
64919 + TE_LINK_L_LIST *pTeLinks;
64921 + pTeLinks = TeLinkLListHead;
64922 + while (pTeLinks != NULL)
64924 + BwUpdateRequest2Igp (pTeLinks->te_link);
64925 + /* component links are not processed yet */
64926 + pTeLinks = pTeLinks->next;
64928 + return E_OK;
64931 +/*****************************************************************************
64933 + PROCEDURE NAME: rdb_remote_link_router_id_get
64935 + DESCRIPTION: This function is called to determine that link belongs to certain router.
64937 + PARAMETERS: rdb_handle - Routing Data Base handle.
64938 + from_node - Local IP address of the TE link.
64939 + router_id - Router ID, to which this link belongs.
64941 +*****************************************************************************/
64943 +uns32
64944 +rdb_remote_link_router_id_mapping_dump (struct vty * vty)
64946 + LINK_2_ROUTER_ID *pLink2RouterId;
64947 + IPV4_ADDR key = 0;
64949 + vty_out (vty, "%s", VTY_NEWLINE);
64951 + while ((pLink2RouterId =
64952 + (LINK_2_ROUTER_ID *) patricia_tree_getnext (&Link2RouterIdTree,
64953 + (const uns8 *) &key)) !=
64954 + NULL)
64956 + vty_out (vty, "LinkID %x RouterID %x%s", pLink2RouterId->link_id,
64957 + pLink2RouterId->router_id, VTY_NEWLINE);
64958 + key = pLink2RouterId->link_id;
64960 + vty_out (vty, "%s", VTY_NEWLINE);
64961 + return E_OK;
64964 +/*****************************************************************************
64966 + PROCEDURE NAME: rdb_te_links_dump
64968 + DESCRIPTION: Displays TE links.
64971 +*****************************************************************************/
64972 +uns32
64973 +rdb_te_links_dump (struct vty * vty)
64975 + TE_LINK_L_LIST *pTeLinks;
64976 + COMPONENT_LINK *pComponentLink;
64977 + int j, i;
64979 + pTeLinks = TeLinkLListHead;
64980 + vty_out (vty, "%s", VTY_NEWLINE);
64981 + while (pTeLinks != NULL)
64983 + vty_out (vty,
64984 + "TE LINK ID %x type %x MaxLspBW %f MaxReservableBW %f TE metric %x color mask %x%s",
64985 + pTeLinks->te_link->te_link_id, pTeLinks->te_link->type,
64986 + pTeLinks->te_link->te_link_properties.MaxLspBW,
64987 + pTeLinks->te_link->te_link_properties.MaxReservableBW,
64988 + pTeLinks->te_link->te_link_properties.TeMetric,
64989 + pTeLinks->te_link->te_link_properties.color_mask, VTY_NEWLINE);
64990 + vty_out (vty, "ReservableBW (0-7):%s", VTY_NEWLINE);
64991 + for (j = 0; j < 8; j++)
64992 + vty_out (vty, " %f",
64993 + pTeLinks->te_link->te_link_properties.ReservableBW[j]);
64995 + vty_out (vty, "%s", VTY_NEWLINE);
64997 + pComponentLink = pTeLinks->te_link->component_links;
64998 + while (pComponentLink != NULL)
65000 + vty_out (vty, "Out IF %x%s", pComponentLink->oifIndex, VTY_NEWLINE);
65001 + vty_out (vty, "ConfiguredReservable BW (0 -7):%s", VTY_NEWLINE);
65002 + for (j = 0; j < 8; j++)
65003 + vty_out (vty, " %f", pComponentLink->ConfiguredReservableBW[j]);
65004 + vty_out (vty, "Reservable BW (0 -7):%s", VTY_NEWLINE);
65005 + for (j = 0; j < 8; j++)
65006 + vty_out (vty, " %f", pComponentLink->ReservableBW[j]);
65007 + vty_out (vty, "ALLOCATED:");
65008 + for (j = 0; j < 8; j++)
65010 + vty_out (vty, "%s", VTY_NEWLINE);
65011 + for (i = 0; i < 8; i++)
65013 + vty_out (vty, " %f", pComponentLink->AllocatedBW[j][i]);
65016 + vty_out (vty, "%s", VTY_NEWLINE);
65017 + pComponentLink = pComponentLink->next;
65019 + pTeLinks = pTeLinks->next;
65021 + return E_OK;
65025 +/*****************************************************************************
65027 + PROCEDURE NAME: rdb_next_hop_dump
65029 + DESCRIPTION: Displays Next Hops.
65032 +*****************************************************************************/
65033 +uns32
65034 +rdb_next_hop_dump (struct vty * vty)
65036 + RDB_NEXT_HOP *next_hop_entry;
65037 + IPV4_ADDR key_ip;
65038 + int j;
65040 + vty_out (vty, "%s", VTY_NEWLINE);
65042 + key_ip = 0;
65044 + while ((next_hop_entry =
65045 + (RDB_NEXT_HOP *) patricia_tree_getnext (&NextHopTree,
65046 + (const uns8 *) &key_ip)) !=
65047 + NULL)
65049 + TE_LINK_L_LIST *pTeLink;
65050 + COMPONENT_LINK *pComponentLink;
65052 + pTeLink = next_hop_entry->TELinkLList;
65053 + vty_out (vty, "Next Hop %x%s", next_hop_entry->dest, VTY_NEWLINE);
65054 + while (pTeLink != NULL)
65056 + switch (pTeLink->te_link->type)
65058 + case PSC_PATH:
65059 + vty_out (vty, "TE LINK ID %x%s", pTeLink->te_link->te_link_id,
65060 + VTY_NEWLINE);
65061 + vty_out (vty,
65062 + "MaxLspBW %f MaxReservableBW %f TE metric %x Color Mask %x%s",
65063 + pTeLink->te_link->te_link_properties.MaxLspBW,
65064 + pTeLink->te_link->te_link_properties.MaxReservableBW,
65065 + pTeLink->te_link->te_link_properties.TeMetric,
65066 + pTeLink->te_link->te_link_properties.color_mask,
65067 + VTY_NEWLINE);
65068 + vty_out (vty, "ReservableBW (0-7):%s", VTY_NEWLINE);
65069 + for (j = 0; j < 8; j++)
65070 + vty_out (vty, " %f",
65071 + pTeLink->te_link->te_link_properties.
65072 + ReservableBW[j]);
65073 + break;
65074 + default:
65075 + zlog_info ("\nIS not supported %s %d", __FILE__, __LINE__);
65077 + pComponentLink = pTeLink->te_link->component_links;
65078 + while (pComponentLink != NULL)
65080 + vty_out (vty, "Out IF %x%s", pComponentLink->oifIndex,
65081 + VTY_NEWLINE);
65082 + vty_out (vty, "ReservableBW (0-7):%s", VTY_NEWLINE);
65083 + for (j = 0; j < 8; j++)
65084 + vty_out (vty, " %f", pComponentLink->ReservableBW[j]);
65085 + pComponentLink = pComponentLink->next;
65087 + pTeLink = pTeLink->next;
65089 + key_ip = next_hop_entry->dest;
65091 + /** Ok do the ifaddr list now.
65092 + **/
65093 + vty_out (vty, "%s", VTY_NEWLINE);
65094 + return E_OK;
65098 +/*****************************************************************************
65100 + PROCEDURE NAME: rdb_summary_dump
65102 + DESCRIPTION: Displays summary advertisements.
65105 +*****************************************************************************/
65106 +uns32
65107 +rdb_summary_dump ()
65109 + RDB_ABRS *abr_entry;
65110 + IPV4_ADDR key_ip;
65111 + int j;
65113 + zlog_debug ("\n\n");
65115 + key_ip = 0;
65117 + while ((abr_entry = (RDB_ABRS *) patricia_tree_getnext (&ASBorderTree,
65118 + (const uns8 *)
65119 + &key_ip)) != NULL)
65121 + ABRS_L_LIST *pAbrsList;
65122 + int i;
65124 + pAbrsList = abr_entry->AbrsLList;
65125 + zlog_debug ("\nASBR %x", abr_entry->dest);
65126 + while (pAbrsList != NULL)
65128 + SUMMARY_PROPERTIES *pProperties = pAbrsList->Abr->SummaryProperties;
65129 + zlog_debug ("\nABR %x", pAbrsList->Abr->AbrIpAddr);
65130 + for (i = 0; i < pAbrsList->Abr->NumberOfSummaries; i++)
65132 + zlog_debug ("\nMaxLspBW %f", pProperties->SummaryMaxLspBW);
65133 + zlog_debug ("\nMaxReservableBW %f",
65134 + pProperties->SummaryMaxReservableBW);
65135 + zlog_debug ("\nReservableBW (0-7):");
65136 + for (j = 0; j < 8; j++)
65137 + zlog_debug (" %f", pProperties->SummaryReservableBW[j]);
65138 + pProperties++;
65140 + pAbrsList = pAbrsList->next;
65142 + key_ip = abr_entry->dest;
65145 + /** Ok do the ifaddr list now.
65146 + **/
65147 + zlog_debug ("\n\n");
65148 + return E_OK;
65151 +/*****************************************************************************
65153 + PROCEDURE NAME: rdb_path_dump
65155 + DESCRIPTION: Displays the paths.
65158 +*****************************************************************************/
65159 +uns32
65160 +rdb_path_dump (struct vty * vty)
65162 + RDB_PATH *path_entry;
65163 + IPV4_ADDR key_ip;
65164 + int j;
65166 + key_ip = 0;
65167 + vty_out (vty, "%s", VTY_NEWLINE);
65168 + while ((path_entry = (RDB_PATH *) patricia_tree_getnext (&AreaBorderTree,
65169 + (const uns8 *)
65170 + &key_ip)) != NULL)
65172 + PATH_L_LIST *pPathList;
65173 + int i;
65175 + pPathList = path_entry->PathLList;
65176 + vty_out (vty, "Path to ABR %x%s", path_entry->dest, VTY_NEWLINE);
65177 + while (pPathList != NULL)
65179 + ER_HOP_L_LIST *er_hop_l_list;
65180 + er_hop_l_list = pPathList->pPath->u.er_hops_l_list;
65181 + switch (pPathList->pPath->PathProperties.PathType)
65183 + case PSC_PATH:
65184 + case LSC_PATH:
65185 + case FSC_PATH:
65186 + case TSC_PATH:
65187 + for (i = 0;
65188 + i < (pPathList->pPath->PathProperties.PathHopCount) &&
65189 + (er_hop_l_list != NULL); i++)
65191 + vty_out (vty, "%x %x -->", er_hop_l_list->er_hop->local_ip,
65192 + er_hop_l_list->er_hop->remote_ip);
65193 + er_hop_l_list = er_hop_l_list->next;
65195 + break;
65197 + default:
65198 + zlog_info ("This path type %d is not supported",
65199 + pPathList->pPath->PathProperties.PathType);
65201 + vty_out (vty,
65202 + "MaxLspBW %f MaxReservableBW %f TE metric %x Hop count %x Color Mask %x%s",
65203 + pPathList->pPath->PathProperties.PathMaxLspBW,
65204 + pPathList->pPath->PathProperties.PathMaxReservableBW,
65205 + pPathList->pPath->PathProperties.PathSumTeMetric,
65206 + pPathList->pPath->PathProperties.PathHopCount,
65207 + pPathList->pPath->PathProperties.PathColorMask,
65208 + VTY_NEWLINE);
65209 + vty_out (vty, "ReservableBW (0-7):%s", VTY_NEWLINE);
65210 + for (j = 0; j < 8; j++)
65211 + vty_out (vty, " %f",
65212 + pPathList->pPath->PathProperties.PathReservableBW[j]);
65214 + pPathList = pPathList->next;
65216 + key_ip = path_entry->dest;
65218 + vty_out (vty, "%s", VTY_NEWLINE);
65219 + return E_OK;
65222 +/*****************************************************************************
65224 + PROCEDURE NAME: rdb_remote_link_dump
65226 + DESCRIPTION: Displays the remote links.
65229 +*****************************************************************************/
65231 +uns32
65232 +rdb_remote_link_dump (struct vty * vty)
65234 + TE_HOP *pKxErHop;
65235 + link_key_t link_key;
65236 + int i, j;
65238 + vty_out (vty, "%s", VTY_NEWLINE);
65240 + link_key.local_ip = 0;
65241 + link_key.remote_ip = 0;
65243 + for (i = 0; i < (MAX_PATH_TYPE - 1); i++)
65245 + while ((pKxErHop =
65246 + (TE_HOP *) patricia_tree_getnext (&(RemoteLinkTree[i - 1]),
65247 + (const uns8 *) &link_key)) !=
65248 + NULL)
65250 + vty_out (vty, "Link %x->%x%s", pKxErHop->local_ip,
65251 + pKxErHop->remote_ip, VTY_NEWLINE);
65253 + vty_out (vty,
65254 + "MaxLspBW %f MaxReservableBW %f TE metric %x ColorMask %x %s",
65255 + pKxErHop->MaxLspBW, pKxErHop->MaxReservableBW,
65256 + pKxErHop->te_metric, pKxErHop->ColorMask, VTY_NEWLINE);
65257 + vty_out (vty, "ReservableBW (0-7):%s", VTY_NEWLINE);
65258 + for (j = 0; j < 8; j++)
65259 + vty_out (vty, " %f", pKxErHop->ReservableBW[j]);
65260 +#if 0
65261 + pPathList = pKxErHop->pPathList;
65262 + while (pPathList != NULL)
65264 + ER_HOP_L_LIST *er_hop_l_list;
65265 + er_hop_l_list = pPathList->pPath->u.er_hops_l_list;
65266 + if ((i + 1) != pPathList->pPath->PathProperties.PathType)
65268 + zlog_info ("expected path type %d, existing %d",
65269 + (i + 1),
65270 + pPathList->pPath->PathProperties.PathType);
65272 + zlog_info ("");
65273 + for (j = 0;
65274 + j < (pPathList->pPath->PathProperties.PathHopCount) &&
65275 + (er_hop_l_list != NULL); j++)
65277 + zlog_info ("%x %x -->", er_hop_l_list->er_hop->local_ip,
65278 + er_hop_l_list->er_hop->remote_ip);
65279 + er_hop_l_list = er_hop_l_list->next;
65281 + zlog_info
65282 + ("MaxLspBW %f MaxReservableBW %f TE metric %x Hop count %x Color Mask %x",
65283 + pPathList->pPath->PathProperties.PathMaxLspBW,
65284 + pPathList->pPath->PathProperties.PathMaxReservableBW,
65285 + pPathList->pPath->PathProperties.PathSumTeMetric,
65286 + pPathList->pPath->PathProperties.PathHopCount,
65287 + pPathList->pPath->PathProperties.PathColorMask);
65288 + zlog_info ("ReservableBW (0-7):");
65289 + for (j = 0; j < 8; j++)
65290 + zlog_info (" %f",
65291 + pPathList->pPath->PathProperties.
65292 + PathReservableBW[j]);
65293 + pPathList = pPathList->next;
65295 +#endif
65296 + link_key.local_ip = pKxErHop->local_ip;
65297 + link_key.remote_ip = pKxErHop->remote_ip;
65300 + vty_out (vty, "%s", VTY_NEWLINE);
65301 + return E_OK;
65304 +/*****************************************************************************
65306 + PROCEDURE NAME: rdb_static_path_dump
65308 + DESCRIPTION: Adds a new path *pPath to destination dest_ip.
65310 + PARAMETERS: rdb_handle - Routing Data Base handle.
65311 + dest_ip - Path destination's IP address.
65312 + *pPath - pointer to the path description (path's summary propertieslist of hops
65313 + and hops' properties).
65315 +*****************************************************************************/
65316 +uns32
65317 +rdb_static_path_dump (char *pName, struct vty * vty)
65319 + STATIC_PATH *pStaticPath;
65320 + IPV4_HOP *pHops;
65322 + vty_out (vty, "%s", VTY_NEWLINE);
65323 + pStaticPath = StaticPathHead;
65324 + while (pStaticPath != NULL)
65326 + if (pName)
65328 + if (strcmp (pName, pStaticPath->PathName) != 0)
65330 + pStaticPath = pStaticPath->next;
65331 + continue;
65334 + vty_out (vty, "Path %s%s", pStaticPath->PathName, VTY_NEWLINE);
65335 + vty_out (vty, "Hops (%d): %s", pStaticPath->HopCount, VTY_NEWLINE);
65336 + for (pHops = pStaticPath->HopList; pHops; pHops = pHops->next)
65338 + vty_out (vty, " Loose %x IP Address %x %s",
65339 + pHops->Loose, pHops->IpAddr, VTY_NEWLINE);
65341 + if (pName)
65343 + if (strcmp (pName, pStaticPath->PathName) == 0)
65345 + break;
65348 + pStaticPath = pStaticPath->next;
65350 + vty_out (vty, "%s", VTY_NEWLINE);
65351 + return E_OK;
65353 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_rdb.h quagga-mpls/rsvpd/te_rdb.h
65354 --- quagga/rsvpd/te_rdb.h 1969-12-31 18:00:00.000000000 -0600
65355 +++ quagga-mpls/rsvpd/te_rdb.h 2007-06-18 23:55:58.000000000 -0500
65356 @@ -0,0 +1,238 @@
65357 +#ifndef RDB_H
65358 +#define RDB_H
65360 +typedef enum
65362 + EMPTY_PATH,
65363 + PSC_PATH,
65364 + LSC_PATH,
65365 + FSC_PATH,
65366 + TSC_PATH,
65367 + PSC_LSP,
65368 + LSC_LSP,
65369 + FSC_LSP,
65370 + TSC_LSP,
65371 + MAX_PATH_TYPE
65372 +} PATH_TYPE;
65374 +typedef struct _link_properties_
65376 + PATH_TYPE LinkType;
65377 + uns32 LinkCost;
65378 + float LinkMaxReservableBW;
65379 + float LinkReservableBW[8];
65380 + float LinkMaxLspBW;
65381 + uns32 LinkTeMetric;
65382 + uns32 LinkColorMask;
65383 +} LINK_PROPERTIES;
65385 +typedef struct _path_properties_
65387 + PATH_TYPE PathType;
65388 + uns32 PathCost;
65389 + float PathMaxReservableBW;
65390 + float PathReservableBW[8];
65391 + float PathMaxLspBW;
65392 + uns32 PathSumTeMetric;
65393 + uns32 PathColorMask;
65394 + uns8 PathHopCount;
65395 +} PATH_PROPERTIES;
65397 +#if 0
65398 +typedef struct
65400 + IPV4_ADDR local_ip_addr;
65401 + IPV4_ADDR remote_ip_addr;
65402 + float MaxReservableBW;
65403 + float ReservableBW[8];
65404 + float MaxLspBW;
65405 + uns32 te_metric;
65406 + uns32 ColorMask;
65407 +} TE_HOP;
65408 +#else
65409 +typedef struct _path_l_list_
65411 + struct _path_ *pPath;
65412 + struct _path_l_list_ *next;
65413 +} PATH_L_LIST;
65415 +typedef struct
65417 + PATRICIA_NODE Node;
65418 + IPV4_ADDR local_ip;
65419 + IPV4_ADDR remote_ip;
65420 + IPV4_ADDR adv_router_id;
65421 + float MaxReservableBW;
65422 + float ReservableBW[8];
65423 + float MaxLspBW;
65424 + uns32 te_metric;
65425 + uns32 ColorMask;
65426 + uns32 Cost;
65427 + PATH_L_LIST *pPathList;
65428 +} TE_HOP;
65429 +#endif
65431 +typedef struct
65433 + IPV4_ADDR local_ip;
65434 + IPV4_ADDR remote_ip;
65435 +} link_key_t;
65437 +typedef struct
65439 + PATH_TYPE SummaryPathType;
65440 + float SummaryMaxLspBW;
65441 + float SummaryMaxReservableBW;
65442 + float SummaryReservableBW[8];
65443 + uns32 SummaryCost;
65444 +} SUMMARY_PROPERTIES;
65446 +typedef struct _abr_
65448 + IPV4_ADDR AbrIpAddr;
65449 + uns8 NumberOfSummaries;
65450 + SUMMARY_PROPERTIES *SummaryProperties;
65451 +} ABR;
65453 +typedef struct _te_link_properties_
65455 + float MaxReservableBW;
65456 + float ReservableBW[8];
65457 + float MaxLspBW;
65458 + uns32 TeMetric;
65459 + uns32 color_mask;
65460 +} TE_LINK_PROPERTIES;
65462 +typedef struct _component_link_
65464 + uns32 oifIndex;
65465 + float ReservableBW[8];
65466 + float ConfiguredReservableBW[8];
65467 + float AllocatedBW[8][8];
65468 + PATRICIA_TREE ProtectionTree;
65469 + PATRICIA_TREE IngressProtectionTree;
65470 + struct _component_link_ *next;
65471 +} COMPONENT_LINK;
65473 +typedef struct _te_link_
65475 + uns32 te_link_id;
65476 + uns8 Status;
65477 + PATH_TYPE type;
65478 + TE_LINK_PROPERTIES te_link_properties;
65479 + PATRICIA_TREE NeighborsTree;
65480 + COMPONENT_LINK *component_links;
65481 +} TE_LINK;
65484 +typedef struct
65486 + PATRICIA_NODE Node;
65487 + IPV4_ADDR link_id;
65488 + IPV4_ADDR router_id;
65489 +} LINK_2_ROUTER_ID;
65491 +typedef struct _er_hop_l_list_
65493 + TE_HOP *er_hop;
65494 + struct _er_hop_l_list_ *next;
65495 +} ER_HOP_L_LIST;
65497 +typedef struct _path_
65499 + IPV4_ADDR destination;
65500 + PATH_PROPERTIES PathProperties;
65501 + union
65503 + ER_HOP_L_LIST *er_hops_l_list;
65504 + TE_HOP *er_hops;
65505 + } u;
65506 +} PATH;
65508 +typedef struct _abrs_l_list_
65510 + ABR *Abr;
65511 + struct _abrs_l_list_ *next;
65512 +} ABRS_L_LIST;
65514 +typedef struct _te_link_l_list_
65516 + TE_LINK *te_link;
65517 + struct _te_link_l_list_ *next;
65518 +} TE_LINK_L_LIST;
65520 +typedef struct _ipv4_hop_
65522 + IPV4_ADDR IpAddr;
65523 + int Loose;
65524 + struct _ipv4_hop_ *next;
65525 +} IPV4_HOP;
65527 +typedef struct _static_path_l_list_
65529 + char PathName[32];
65530 + int HopCount;
65531 + IPV4_HOP *HopList;
65532 + struct _static_path_l_list_ *next;
65533 +} STATIC_PATH;
65535 +uns32 AmIDestination (IPV4_ADDR dest, uns32 * pDestIf);
65536 +uns32 IsDestinationNextHop (IPV4_ADDR dest, TE_LINK_L_LIST ** ppTeLinks);
65537 +uns32 IsDestinationIntraArea (IPV4_ADDR dest, PATH_L_LIST ** ppPaths);
65538 +uns32 GetPathNumber (IPV4_ADDR dest);
65539 +uns32 IsDestinationASBorder (IPV4_ADDR dest, ABRS_L_LIST ** ppAbrs);
65540 +E_RC rdb_create ();
65541 +uns32 rdb_destroy ();
65542 +uns32 rdb_add_component_link (uns32 TeLinkId,
65543 + COMPONENT_LINK * pComponentLink);
65544 +uns32 rdb_delete_component_link (uns32 TeLinkId, uns32 oIfIndex);
65545 +uns32 rdb_get_component_link (uns32 TeLinkId, uns32 IfIndex,
65546 + COMPONENT_LINK ** ppCompLink);
65547 +uns32 rdb_add_mod_path (IPV4_ADDR dest_ip, PATH * pPath);
65548 +uns32 rdb_connectivity_broken (IPV4_ADDR from_node, IPV4_ADDR to_node,
65549 + PATH_TYPE path_type);
65550 +uns32 rdb_link_state_update (IPV4_ADDR from_node, IPV4_ADDR to_node,
65551 + LINK_PROPERTIES * pLinkProperties);
65552 +uns32 rdb_remote_link_bw_update (IPV4_ADDR from_node, IPV4_ADDR to_node,
65553 + float BW2Decrease, uns8 Priority,
65554 + PATH_TYPE LinkSwitchCap);
65555 +uns32 rdb_remote_link_2_router_id_mapping (IPV4_ADDR link_id,
65556 + IPV4_ADDR router_id);
65557 +uns32 rdb_remote_link_2_router_id_mapping_withdraw (IPV4_ADDR link_id);
65558 +uns32 rdb_set_router_id (IPV4_ADDR IpAddr);
65559 +IPV4_ADDR rdb_get_router_id ();
65560 +uns32 rdb_remote_link_router_id_get (IPV4_ADDR from_node,
65561 + IPV4_ADDR * router_id);
65562 +uns32 rdb_static_path_del_hop_by_index (char *StaticPathName, int index);
65563 +uns32 rdb_static_path_del_hop (char *StaticPathName, IPV4_ADDR IpAddr);
65564 +uns32 rdb_static_path_add_hop_by_index (char *StaticPathName,
65565 + IPV4_ADDR IpAddr, int Loose,
65566 + int index);
65567 +uns32 rdb_static_path_add_hop_after_index (char *StaticPathName,
65568 + IPV4_ADDR IpAddr, int Loose,
65569 + int index);
65570 +uns32 rdb_static_path_add_hop (char *StaticPathName, IPV4_ADDR IpAddr,
65571 + int Loose);
65572 +uns32 rdb_get_static_path (char *pName, STATIC_PATH ** ppStaticPath);
65573 +uns32 rdb_create_static_path (char *StaticPathName);
65574 +uns32 rdb_delete_static_path (char *StaticPathName);
65575 +uns32 rdb_delete_asbr (IPV4_ADDR asbr_ip, IPV4_ADDR abr_ip);
65576 +uns32 rdb_add_mod_summary (IPV4_ADDR asbr_ip, ABR * pAbr);
65577 +uns32 rdb_del_next_hop (IPV4_ADDR next_hop, uns32 te_link_id);
65578 +uns32 rdb_local_link_status_change (uns32 TeLinkId, uns8 Status);
65579 +uns32 rdb_add_next_hop (IPV4_ADDR next_hop, uns32 TeLinkId);
65580 +uns32 rdb_del_te_link (uns32 te_link_id);
65581 +uns32 rdb_add_te_link (TE_LINK * pTeLink);
65582 +void rdb_te_link_max_lsp_bw_calc (TE_LINK * pTeLink);
65583 +uns32 rdb_get_te_link (uns32 TeLinkId, TE_LINK ** ppTeLink);
65585 +uns32 rdb_next_hop_dump (struct vty *vty);
65586 +uns32 rdb_summary_dump ();
65587 +uns32 rdb_path_dump (struct vty *vty);
65588 +uns32 rdb_remote_link_dump (struct vty *vty);
65589 +uns32 rdb_static_path_dump (char *, struct vty *vty);
65590 +uns32 rdb_te_links_dump (struct vty *vty);
65591 +uns32 rdb_remote_link_router_id_mapping_dump (struct vty *vty);
65592 +uns32 rdb_igp_hello ();
65594 +#endif
65595 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_tr.c quagga-mpls/rsvpd/te_tr.c
65596 --- quagga/rsvpd/te_tr.c 1969-12-31 18:00:00.000000000 -0600
65597 +++ quagga-mpls/rsvpd/te_tr.c 2007-06-19 00:09:56.000000000 -0500
65598 @@ -0,0 +1,430 @@
65599 +/* Module: transit_req_sm.c
65600 + Contains: TE application transit PATH message processing
65601 + Module creator: Vadim Suraev, vadim_suraev@hotmail.com
65602 + */
65603 +#include "te.h"
65605 +static SM_CALL_T *transit_req_sm_empty_handler (SM_T * pSm,
65606 + SM_EVENT_T * sm_data);
65607 +static SM_CALL_T *transit_req_sm_init (SM_T * pSm, SM_EVENT_T * sm_data);
65608 +static SM_CALL_T *transit_req_sm_constraint_route_resolution (SM_T * pSm,
65609 + SM_EVENT_T *
65610 + sm_data);
65611 +static void TransitReqSmDestroy (SM_T * pSm);
65613 +static SM_CALL_T *
65614 +transit_req_sm_empty_handler (SM_T * pSm, SM_EVENT_T * sm_data)
65616 + zlog_err ("new_transit_req_sm_empty_handler, state %d", pSm->state);
65617 + return NULL;
65620 +static SM_CALL_T *
65621 +transit_req_sm_init (SM_T * pSm, SM_EVENT_T * sm_event)
65623 + SM_CALL_T *pCall = NULL;
65624 + TRANSIT_REQ_SM_DATA *pTransitReqSmData = NULL;
65625 + CONSTRAINT_ROUTE_RESOLUTION_ARGS *pCrArgs;
65626 + PATH_NOTIFICATION *pTransitReqParams;
65628 + switch (sm_event->event)
65630 + case TRANSIT_REQ_EVENT:
65631 + sm_gen_event_trace (sm_event->event);
65633 + if ((pTransitReqSmData =
65634 + (TRANSIT_REQ_SM_DATA *) XMALLOC (MTYPE_TE,
65635 + sizeof (TRANSIT_REQ_SM_DATA))) ==
65636 + NULL)
65638 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
65639 + TransitReqSmDestroy (pSm);
65640 + return NULL;
65643 + pTransitReqSmData->pTransitReqParams = sm_event->data;
65644 + pSm->data = pTransitReqSmData;
65645 + pTransitReqParams = pTransitReqSmData->pTransitReqParams;
65647 + if ((pCrArgs =
65648 + (CONSTRAINT_ROUTE_RESOLUTION_ARGS *) XMALLOC (MTYPE_TE,
65649 + sizeof
65650 + (CONSTRAINT_ROUTE_RESOLUTION_ARGS)))
65651 + == NULL)
65653 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
65654 + TransitReqSmDestroy (pSm);
65655 + return NULL;
65657 + pCrArgs->BW = pTransitReqParams->BW;
65658 + zlog_info ("\npCrArgs->BW %d", pCrArgs->BW);
65659 + if (pTransitReqParams->ErHopNumber != 0)
65661 + zlog_info ("\ndestination %x", pTransitReqParams->ErHops[0]);
65662 + pCrArgs->dest = pTransitReqParams->ErHops[0];
65664 + else
65666 + pCrArgs->dest = ntohl (pTransitReqParams->PsbKey.Session.Dest);
65667 + zlog_info ("\ndestination1 %x",
65668 + pTransitReqParams->PsbKey.Session.Dest);
65671 + pCrArgs->PsbKey.Session = pTransitReqParams->PsbKey.Session;
65673 + if (pTransitReqParams->RA_Valid == TRUE)
65675 + zlog_info
65676 + ("\nSESSION ATTRIBUTES: SetPrio %x HoldPrio %x Shared %x FRR %x LabelRecording %x ExclAny %x InclAny %x InclAll %x",
65677 + pTransitReqParams->SetupPrio, pTransitReqParams->HoldPrio,
65678 + pTransitReqParams->SharedExplicit,
65679 + pTransitReqParams->LocalProtection,
65680 + pTransitReqParams->LabelRecordingDesired,
65681 + pTransitReqParams->ExcludeAny, pTransitReqParams->IncludeAny,
65682 + pTransitReqParams->IncludeAll);
65683 + pCrArgs->SetupPriority = pTransitReqParams->SetupPrio;
65684 + pCrArgs->HoldPriority = pTransitReqParams->HoldPrio;
65685 + pCrArgs->ExclColorMask = pTransitReqParams->ExcludeAny;
65686 + pCrArgs->InclColorMask = pTransitReqParams->IncludeAny;
65688 + else
65690 + zlog_info ("\nSESSION ATTRIBUTES: %x %x %x %x %x",
65691 + pTransitReqParams->SetupPrio,
65692 + pTransitReqParams->HoldPrio,
65693 + pTransitReqParams->SharedExplicit,
65694 + pTransitReqParams->LocalProtection,
65695 + pTransitReqParams->LocalProtection);
65696 + pCrArgs->SetupPriority = pTransitReqParams->SetupPrio;
65697 + pCrArgs->HoldPriority = pTransitReqParams->HoldPrio;
65700 + if ((pCall =
65701 + (SM_CALL_T *) constraint_route_resolution_sm_invoke (pSm,
65702 + pCrArgs)) ==
65703 + NULL)
65705 + zlog_err ("\ncannot invoke constraint route resolution sm");
65706 + XFREE (MTYPE_TE, pCrArgs);
65707 + TransitReqSmDestroy (pSm);
65709 + pSm->state = TRANSIT_REQ_SM_CONSTRAINT_ROUTE_RESOLUTION_STATE;
65710 + break;
65711 + default:
65712 + zlog_err ("\nunexpected event %d %s %d",
65713 + sm_event->event, __FILE__, __LINE__);
65714 + TransitReqSmDestroy (pSm);
65716 + return pCall;
65719 +static SM_CALL_T *
65720 +transit_req_sm_constraint_route_resolution (SM_T * pSm, SM_EVENT_T * sm_event)
65722 + TRANSIT_REQ_SM_DATA *pTransitReqSmData = NULL;
65723 + CONSTRAINT_ROUTE_RESOLUTION_ARGS *pCrArgs;
65724 + PATH_NOTIFICATION *pTransitReqParams;
65725 + PSB_KEY PsbKey;
65726 + TE_API_MSG dmsg;
65727 + SM_CALL_T *pCall = NULL;
65728 + int i;
65729 + unsigned int label = 0;
65732 + pCrArgs = sm_event->data;
65734 + switch (sm_event->event)
65736 + case CONSTRAINT_ROUTE_RESOLVED_EVENT:
65737 + sm_gen_event_trace (sm_event->event);
65738 + pTransitReqSmData = pSm->data;
65739 + pTransitReqParams = pTransitReqSmData->pTransitReqParams;
65740 + pTransitReqParams->OutIfIndex = pCrArgs->OutIf;
65741 + pTransitReqParams->NextHop = ntohl (pCrArgs->OutNHop);
65744 + if (pCrArgs->rc == OUTPUT_CAC_FAILED)
65746 + pTransitReqParams->rc = BW_UNAVAIL;
65748 + else if (pCrArgs->rc == OUTPUT_UNREACHABLE)
65750 + pTransitReqParams->rc = NO_ROUTE;
65752 + else if (pCrArgs->rc == OUTPUT_NEXT_HOP)
65754 + pTransitReqParams->rc = PATH_PROC_OK;
65756 + else if (pCrArgs->rc == OUTPUT_PATH)
65758 + /* copy path here */
65759 + pTransitReqParams->ErHopNumber = pCrArgs->data.path.ErHopNumber;
65760 + for (i = 0; i < pTransitReqParams->ErHopNumber; i++)
65762 + pTransitReqParams->ErHops[i] = pCrArgs->data.path.pErHop[i];
65764 + pTransitReqParams->rc = PATH_PROC_OK;
65766 + else if (pCrArgs->rc == OUTPUT_LSP)
65768 + zlog_info ("\nTunneled %x", pTransitReqParams->ErHopNumber);
65769 + pTransitReqParams->ErHopNumber = 0;
65770 + zlog_info ("\nLSP HIERARCHY is not supported currently");
65771 + XFREE (MTYPE_TE, pCrArgs);
65772 + TransitReqSmDestroy (pSm);
65773 + return NULL;
65775 + else
65777 + zlog_err ("\nunknown RC");
65778 + XFREE (MTYPE_TE, pCrArgs);
65779 + TransitReqSmDestroy (pSm);
65780 + return NULL;
65783 + memset (&PsbKey, 0, sizeof (PSB_KEY));
65785 + PsbKey.Session = pTransitReqParams->PsbKey.Session;
65787 + if (LabelAllocate
65788 + (&label, ALL_LABELS, &PsbKey,
65789 + pTransitReqParams->OutIfIndex) != E_OK)
65791 + zlog_err ("\ncannot allocate label %s %d", __FILE__, __LINE__);
65792 + pTransitReqParams->Label = 0;
65794 + else
65795 + pTransitReqParams->Label = label;
65797 + dmsg.NotificationType = PATH_MSG_NOTIFICATION;
65798 + memcpy (&dmsg.u.PathNotification,
65799 + pTransitReqParams, sizeof (PATH_NOTIFICATION));
65801 + te_send_msg (&dmsg, sizeof (TE_API_MSG));
65802 +#ifdef FRR_SM_DEFINED
65803 + if (pTransitReqParams)
65805 + if ((pCrArgs->rc == OUTPUT_PATH) &&
65806 + (pTransitReqParams->ErHopNumber > 1))
65808 + FRR_SM_CALL frr_sm_call;
65809 + int k;
65810 + IPV4_ADDR protected_node_router_id = 0, merge_node_router_id =
65811 + 0, after_merge_node_router_id = 0;
65813 + memset (&frr_sm_call, 0, sizeof (FRR_SM_CALL));
65815 + frr_sm_call.frr_key.OutIfIndex = pTransitReqParams->OutIfIndex;
65817 + if (rdb_remote_link_router_id_get (pTransitReqParams->NextHop,
65818 + &protected_node_router_id) !=
65819 + E_OK)
65821 + protected_node_router_id = pTransitReqParams->NextHop;
65823 + frr_sm_call.frr_key.protected_node = protected_node_router_id;
65824 + for (k = 1; k < pTransitReqParams->ErHopNumber; k++)
65826 + rdb_remote_link_router_id_get (pTransitReqParams->ErHops[k],
65827 + &merge_node_router_id);
65828 + if ((merge_node_router_id != 0) &&
65829 + (merge_node_router_id != protected_node_router_id))
65831 + frr_sm_call.frr_key.merge_node = merge_node_router_id;
65832 + frr_sm_call.MergeNode = pTransitReqParams->ErHops[k];
65833 + break;
65836 + if (frr_sm_call.frr_key.merge_node == 0)
65838 + merge_node_router_id =
65839 + frr_sm_call.frr_key.merge_node =
65840 + pTransitReqParams->ErHops[1];
65841 + frr_sm_call.MergeNode = pTransitReqParams->ErHops[1];
65843 + for (; k < pTransitReqParams->ErHopNumber; k++)
65845 + rdb_remote_link_router_id_get (pTransitReqParams->ErHops[k],
65846 + &after_merge_node_router_id);
65847 + if ((after_merge_node_router_id != 0) &&
65848 + (after_merge_node_router_id != merge_node_router_id))
65850 + frr_sm_call.frr_key.prohibited_penultimate_node =
65851 + after_merge_node_router_id;
65852 + break;
65855 + frr_sm_call.Label = label;
65857 + PsbKey.SenderTemplate =
65858 + pTransitReqParams->PsbKey.SenderTemplate;
65859 + frr_sm_call.PsbKey = PsbKey;
65861 + if ((pCall =
65862 + fast_reroute_sm_sync_invoke (&frr_sm_call,
65863 + BYPASS_SETUP_REQ_EVENT)) ==
65864 + NULL)
65866 + zlog_err ("\ncannot invoke FRR SM %s %d", __FILE__,
65867 + __LINE__);
65870 + else if ((pCrArgs->rc == OUTPUT_NEXT_HOP) &&
65871 + (pTransitReqParams->ErHopNumber > 1))
65873 + FRR_SM_CALL frr_sm_call;
65874 + int k;
65875 + IPV4_ADDR protected_node_router_id = 0, merge_node_router_id =
65876 + 0, after_merge_node_router_id = 0;
65878 + memset (&frr_sm_call, 0, sizeof (FRR_SM_CALL));
65880 + frr_sm_call.frr_key.OutIfIndex = pTransitReqParams->OutIfIndex;
65882 + if (rdb_remote_link_router_id_get (pTransitReqParams->NextHop,
65883 + &protected_node_router_id) !=
65884 + E_OK)
65886 + protected_node_router_id = pTransitReqParams->NextHop;
65888 + frr_sm_call.frr_key.protected_node = protected_node_router_id;
65889 + for (k = 1; k < pTransitReqParams->ErHopNumber; k++)
65891 + rdb_remote_link_router_id_get (pTransitReqParams->ErHops[k],
65892 + &merge_node_router_id);
65893 + if ((merge_node_router_id != 0) &&
65894 + (merge_node_router_id != protected_node_router_id))
65896 + frr_sm_call.frr_key.merge_node = merge_node_router_id;
65897 + frr_sm_call.MergeNode = pTransitReqParams->ErHops[k];
65898 + break;
65901 + if (frr_sm_call.frr_key.merge_node == 0)
65903 + merge_node_router_id =
65904 + frr_sm_call.frr_key.merge_node =
65905 + pTransitReqParams->ErHops[1];
65906 + frr_sm_call.MergeNode = pTransitReqParams->ErHops[1];
65908 + for (; k < pTransitReqParams->ErHopNumber; k++)
65910 + rdb_remote_link_router_id_get (pTransitReqParams->ErHops[k],
65911 + &after_merge_node_router_id);
65912 + if ((after_merge_node_router_id != 0) &&
65913 + (after_merge_node_router_id != merge_node_router_id))
65915 + frr_sm_call.frr_key.prohibited_penultimate_node =
65916 + after_merge_node_router_id;
65917 + break;
65920 + frr_sm_call.Label = label;
65922 + PsbKey.SenderTemplate =
65923 + pTransitReqParams->PsbKey.SenderTemplate;
65924 + frr_sm_call.PsbKey = PsbKey;
65926 + if ((pCall =
65927 + fast_reroute_sm_sync_invoke (&frr_sm_call,
65928 + BYPASS_SETUP_REQ_EVENT)) ==
65929 + NULL)
65931 + zlog_err ("\ncannot invoke FRR SM %s %d", __FILE__,
65932 + __LINE__);
65936 +#endif
65937 + break;
65938 + case CONSTRAINT_ROUTE_RESOLVE_FAILED_EVENT:
65939 + sm_gen_event_trace (sm_event->event);
65940 + pTransitReqSmData = pSm->data;
65941 + pTransitReqParams = pTransitReqSmData->pTransitReqParams;
65942 + pTransitReqParams->ErHopNumber = 0;
65943 + pTransitReqParams->OutIfIndex = 0;
65944 + pTransitReqParams->NextHop = 0;
65947 + pTransitReqParams->rc = NO_ROUTE;
65949 + memset (&PsbKey, 0, sizeof (PSB_KEY));
65951 + PsbKey.Session = pTransitReqParams->PsbKey.Session;
65953 + pTransitReqParams->Label = 0;
65955 + dmsg.NotificationType = PATH_MSG_NOTIFICATION;
65956 + memcpy (&dmsg.u.PathNotification,
65957 + pTransitReqParams, sizeof (PATH_NOTIFICATION));
65959 + te_send_msg (&dmsg, sizeof (TE_API_MSG));
65960 + break;
65961 + default:
65962 + zlog_err ("\nunexpected event %d %s %d",
65963 + sm_event->event, __FILE__, __LINE__);
65965 + XFREE (MTYPE_TE, pCrArgs);
65966 + TransitReqSmDestroy (pSm);
65967 + zlog_info ("\nExiting SM %x...", pCall);
65968 + return pCall;
65971 +static SM_CALL_T
65972 + *(*transit_req_sm_event_handler[TRANSIT_REQ_SM_MAX_STATE]) (SM_T * pSm,
65973 + SM_EVENT_T *
65974 + sm_data) =
65976 +transit_req_sm_empty_handler,
65977 + transit_req_sm_init, transit_req_sm_constraint_route_resolution};
65979 +SM_CALL_T *
65980 +transit_req_sm_handler (SM_T * pSm, SM_EVENT_T * sm_data)
65982 + if (sm_data == NULL)
65984 + zlog_err ("\nfatal: sm_data is NULL %s %d", __FILE__, __LINE__);
65985 + return NULL;
65987 + zlog_info ("\ntransit_req_sm_event_handler. state %d\n", pSm->state);
65988 + if ((pSm->state < INIT_STATE) || (pSm->state >= TRANSIT_REQ_SM_MAX_STATE))
65990 + zlog_err ("\nstate is invalid");
65991 + TransitReqSmDestroy (pSm);
65992 + return NULL;
65994 + return transit_req_sm_event_handler[pSm->state] (pSm, sm_data);
65997 +SM_CALL_T *
65998 +transit_req_sm_invoke (HANDLE caller, void *data)
66000 + SM_T *pNewSm;
66001 + SM_CALL_T *pEvent;
66003 + pNewSm = sm_gen_alloc ((SM_T *) caller, TRANSIT_LSP_SM);
66004 + if (pNewSm == NULL)
66006 + zlog_err ("\nmalloc failed %s %d", __FILE__, __LINE__);
66007 + return NULL;
66009 + if ((pEvent = sm_gen_sync_event_send (pNewSm,
66010 + TRANSIT_REQ_EVENT, data)) == NULL)
66012 + zlog_err ("\ncan not invoke sm %s %d", __FILE__, __LINE__);
66014 + return pEvent;
66017 +static void
66018 +TransitReqSmDestroy (SM_T * pSm)
66020 + TRANSIT_REQ_SM_DATA *pTransitReqSmData = pSm->data;
66021 + PATH_NOTIFICATION *pTransitReqParams = pTransitReqSmData->pTransitReqParams;
66023 + if (pTransitReqParams != NULL)
66024 + XFREE (MTYPE_TE, pTransitReqParams);
66025 + if (pTransitReqSmData != NULL)
66026 + XFREE (MTYPE_TE, pTransitReqSmData);
66027 + sm_gen_free (pSm);
66029 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/rsvpd/te_tr.h quagga-mpls/rsvpd/te_tr.h
66030 --- quagga/rsvpd/te_tr.h 1969-12-31 18:00:00.000000000 -0600
66031 +++ quagga-mpls/rsvpd/te_tr.h 2007-06-18 23:55:58.000000000 -0500
66032 @@ -0,0 +1,18 @@
66034 +#ifndef __TRANSIT_REQ_SM_H__
66035 +#define __TRANSIT_REQ_SM_H__
66037 +typedef enum
66039 + TRANSIT_REQ_SM_CONSTRAINT_ROUTE_RESOLUTION_STATE = INIT_STATE + 1,
66040 + TRANSIT_REQ_SM_MAX_STATE
66041 +} TRANSIT_REQ_SM_STATE_E;
66043 +typedef struct
66045 + PATH_NOTIFICATION *pTransitReqParams;
66046 +} TRANSIT_REQ_SM_DATA;
66048 +SM_CALL_T *transit_req_sm_handler (SM_T * pSm, SM_EVENT_T * sm_data);
66050 +#endif
66051 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/solaris/.cvsignore quagga-mpls/solaris/.cvsignore
66052 --- quagga/solaris/.cvsignore 1969-12-31 18:00:00.000000000 -0600
66053 +++ quagga-mpls/solaris/.cvsignore 2006-08-09 22:02:31.000000000 -0500
66054 @@ -0,0 +1,14 @@
66055 +Makefile
66056 +Makefile.in
66057 +?.manifest
66058 +*.xml
66059 +pkginfo.*.full
66060 +pkginfo.tmpl
66061 +prototype.daemons
66062 +prototype.dev
66063 +prototype.doc
66064 +prototype.libs
66065 +prototype.smf
66066 +quagga.init
66067 +*.pkg
66068 +*.pkg.gz
66069 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/vtysh/extract.pl.in quagga-mpls/vtysh/extract.pl.in
66070 --- quagga/vtysh/extract.pl.in 2008-09-04 20:37:37.000000000 -0500
66071 +++ quagga-mpls/vtysh/extract.pl.in 2008-09-07 20:23:36.000000000 -0500
66072 @@ -31,6 +31,8 @@
66075 $ignore{'"interface IFNAME"'} = "ignore";
66076 +$ignore{'"create tunnel IFNAME"'} = "ignore";
66077 +$ignore{'"tunnel mode mpls"'} = "ignore";
66078 $ignore{'"ip vrf NAME"'} = "ignore";
66079 $ignore{'"router rip"'} = "ignore";
66080 $ignore{'"router ripng"'} = "ignore";
66081 @@ -41,6 +43,9 @@
66082 $ignore{'"router bgp CMD_AS_RANGE view WORD"'} = "ignore";
66083 $ignore{'"router isis WORD"'} = "ignore";
66084 $ignore{'"router zebra"'} = "ignore";
66085 +$ignore{'"mpls ldp"'} = "ignore";
66086 +$ignore{'"mpls ip"'} = "ignore";
66087 +$ignore{'"mpls static <0-255>"'} = "ignore";
66088 $ignore{'"address-family ipv4"'} = "ignore";
66089 $ignore{'"address-family ipv4 (unicast|multicast)"'} = "ignore";
66090 $ignore{'"address-family ipv6"'} = "ignore";
66091 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/vtysh/Makefile.am quagga-mpls/vtysh/Makefile.am
66092 --- quagga/vtysh/Makefile.am 2005-08-25 09:01:20.000000000 -0500
66093 +++ quagga-mpls/vtysh/Makefile.am 2006-12-02 22:34:34.000000000 -0600
66094 @@ -21,14 +21,18 @@
66095 vtysh_cmd_FILES = $(top_srcdir)/bgpd/*.c $(top_srcdir)/isisd/*.c \
66096 $(top_srcdir)/ospfd/*.c $(top_srcdir)/ospf6d/*.c \
66097 $(top_srcdir)/ripd/*.c $(top_srcdir)/ripngd/*.c \
66098 + $(top_srcdir)/ldpd/*.c \
66099 $(top_srcdir)/lib/keychain.c $(top_srcdir)/lib/routemap.c \
66100 $(top_srcdir)/lib/filter.c $(top_srcdir)/lib/plist.c \
66101 $(top_srcdir)/lib/distribute.c $(top_srcdir)/lib/if_rmap.c \
66102 $(top_srcdir)/lib/vty.c $(top_srcdir)/zebra/debug.c \
66103 $(top_srcdir)/zebra/interface.c \
66104 + $(top_srcdir)/zebra/if_tunnel.c \
66105 + $(top_srcdir)/zebra/if_vlan.c \
66106 $(top_srcdir)/zebra/irdp_interface.c \
66107 $(top_srcdir)/zebra/rtadv.c $(top_srcdir)/zebra/zebra_vty.c \
66108 - $(top_srcdir)/zebra/zserv.c $(top_srcdir)/zebra/router-id.c
66109 + $(top_srcdir)/zebra/zserv.c $(top_srcdir)/zebra/router-id.c \
66110 + $(top_srcdir)/zebra/mpls_vty.c
66112 vtysh_cmd.c: $(vtysh_cmd_FILES)
66113 ./$(EXTRA_DIST) $(vtysh_cmd_FILES) > vtysh_cmd.c
66114 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/vtysh/vtysh.c quagga-mpls/vtysh/vtysh.c
66115 --- quagga/vtysh/vtysh.c 2008-09-04 20:37:37.000000000 -0500
66116 +++ quagga-mpls/vtysh/vtysh.c 2008-09-07 20:23:36.000000000 -0500
66117 @@ -57,6 +57,7 @@
66118 { .fd = -1, .name = "ospf6d", .flag = VTYSH_OSPF6D, .path = OSPF6_VTYSH_PATH},
66119 { .fd = -1, .name = "bgpd", .flag = VTYSH_BGPD, .path = BGP_VTYSH_PATH},
66120 { .fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .path = ISIS_VTYSH_PATH},
66121 + { .fd = -1, .name = "ldpd", .flag = VTYSH_LDPD, .path = LDP_VTYSH_PATH},
66124 #define VTYSH_INDEX_MAX (sizeof(vtysh_client)/sizeof(vtysh_client[0]))
66125 @@ -728,12 +729,44 @@
66126 "%s(config-router)# ",
66129 +/* LDP node structure. */
66130 +struct cmd_node mpls_ldp_node =
66132 + LDP_NODE,
66133 + "%s(config-ldp)# ",
66136 +/* MPLS labelspace node structure. */
66137 +struct cmd_node mpls_static_node =
66139 + MPLS_LABELSPACE_NODE,
66140 + "%s(config-ls)# ",
66143 +struct cmd_node tunnel_node =
66145 + TUNNEL_NODE,
66146 + "%s(config-tun)# ",
66149 +struct cmd_node mpls_tunnel_node =
66151 + MPLS_TUNNEL_NODE,
66152 + "%s(config-tun)# ",
66155 struct cmd_node interface_node =
66157 INTERFACE_NODE,
66158 "%s(config-if)# ",
66161 +struct cmd_node ldp_if_node =
66163 + LDP_IF_NODE,
66164 + "%s(config-if-ldp)# ",
66167 struct cmd_node rmap_node =
66169 RMAP_NODE,
66170 @@ -952,6 +985,18 @@
66171 return CMD_SUCCESS;
66174 +DEFUNSH (VTYSH_ZEBRA,
66175 + mpls_static,
66176 + mpls_static_cmd,
66177 + "mpls static <0-255>",
66178 + "Multi-Protocol Label Switching configuration\n"
66179 + "Static label information"
66180 + "Labelspace number (0 = global)")
66182 + vty->node = MPLS_LABELSPACE_NODE;
66183 + return CMD_SUCCESS;
66186 DEFUNSH (VTYSH_RIPD,
66187 router_rip,
66188 router_rip_cmd,
66189 @@ -1008,6 +1053,28 @@
66190 return CMD_SUCCESS;
66193 +DEFUNSH (VTYSH_LDPD,
66194 + vtysh_mpls_ldp,
66195 + vtysh_mpls_ldp_cmd,
66196 + "mpls ldp",
66197 + "Multi-Protocol Label Switching configuration\n"
66198 + "Dynamic label distribution configuration")
66200 + vty->node = LDP_NODE;
66201 + return CMD_SUCCESS;
66204 +DEFUNSH (VTYSH_LDPD,
66205 + vtysh_mpls_ip,
66206 + vtysh_mpls_ip_cmd,
66207 + "mpls ip",
66208 + "MPLS interface configuration\n"
66209 + "Dynamic label distribution via LDP\n")
66211 + vty->node = LDP_IF_NODE;
66212 + return CMD_SUCCESS;
66215 DEFUNSH (VTYSH_RMAP,
66216 route_map,
66217 route_map_cmd,
66218 @@ -1078,9 +1145,13 @@
66219 vty->node = ENABLE_NODE;
66220 break;
66221 case INTERFACE_NODE:
66222 + case TUNNEL_NODE:
66223 + case MPLS_TUNNEL_NODE:
66224 case ZEBRA_NODE:
66225 case BGP_NODE:
66226 case RIP_NODE:
66227 + case LDP_NODE:
66228 + case MPLS_LABELSPACE_NODE:
66229 case RIPNG_NODE:
66230 case OSPF_NODE:
66231 case OSPF6_NODE:
66232 @@ -1103,6 +1174,9 @@
66233 case KEYCHAIN_KEY_NODE:
66234 vty->node = KEYCHAIN_NODE;
66235 break;
66236 + case LDP_IF_NODE:
66237 + vty->node = INTERFACE_NODE;
66238 + break;
66239 default:
66240 break;
66242 @@ -1152,6 +1226,21 @@
66243 "quit",
66244 "Exit current mode and down to previous mode\n")
66246 +DEFUNSH (VTYSH_ZEBRA,
66247 + vtysh_exit_mpls_ls,
66248 + vtysh_exit_mpls_ls_cmd,
66249 + "exit",
66250 + "Exit current mode and down to previous mode\n")
66252 + return vtysh_exit (vty);
66255 +ALIAS (vtysh_exit_mpls_ls,
66256 + vtysh_quit_mpls_ls_cmd,
66257 + "quit",
66258 + "Exit current mode and down to previous mode\n")
66261 DEFUNSH (VTYSH_RIPD,
66262 vtysh_exit_ripd,
66263 vtysh_exit_ripd_cmd,
66264 @@ -1250,6 +1339,34 @@
66265 "quit",
66266 "Exit current mode and down to previous mode\n")
66268 +DEFUNSH (VTYSH_LDPD,
66269 + vtysh_exit_ldpd,
66270 + vtysh_exit_ldpd_cmd,
66271 + "exit",
66272 + "Exit current mode and down to previous mode\n")
66274 + return vtysh_exit (vty);
66277 +ALIAS (vtysh_exit_ldpd,
66278 + vtysh_quit_ldpd_cmd,
66279 + "quit",
66280 + "Exit current mode and down to previous mode\n")
66282 +DEFUNSH (VTYSH_LDPD,
66283 + vtysh_exit_ldp_if,
66284 + vtysh_exit_ldp_if_cmd,
66285 + "exit",
66286 + "Exit current mode and down to previous mode\n")
66288 + return vtysh_exit (vty);
66291 +ALIAS (vtysh_exit_ldp_if,
66292 + vtysh_quit_ldp_if_cmd,
66293 + "quit",
66294 + "Exit current mode and down to previous mode\n")
66296 DEFUNSH (VTYSH_ALL,
66297 vtysh_exit_line_vty,
66298 vtysh_exit_line_vty_cmd,
66299 @@ -1264,6 +1381,52 @@
66300 "quit",
66301 "Exit current mode and down to previous mode\n")
66303 +DEFUNSH (VTYSH_ZEBRA,
66304 + vtysh_exit_tunnel,
66305 + vtysh_exit_tunnel_cmd,
66306 + "exit",
66307 + "Exit current mode and down to previous mode\n")
66309 + return vtysh_exit (vty);
66312 +ALIAS (vtysh_exit_tunnel,
66313 + vtysh_quit_tunnel_cmd,
66314 + "quit",
66315 + "Exit current mode and down to previous mode\n")
66317 +DEFUNSH (VTYSH_ZEBRA,
66318 + vtysh_tunnel,
66319 + vtysh_tunnel_cmd,
66320 + "create tunnel IFNAME",
66321 + "Create virtual interfaces\n"
66322 + "Create a tunnel interface\n"
66323 + "Interface's name\n")
66325 + vty->node = TUNNEL_NODE;
66326 + return CMD_SUCCESS;
66329 +DEFUNSH (VTYSH_ZEBRA,
66330 + vtysh_tunnel_mode_mpls,
66331 + vtysh_tunnel_mode_mpls_cmd,
66332 + "tunnel mode mpls",
66333 + "Tunnel configuration\n"
66334 + "Tunnel mode configuration\n"
66335 + "MPLS\n")
66337 + vty->node = MPLS_TUNNEL_NODE;
66338 + return CMD_SUCCESS;
66341 +DEFSH (VTYSH_ZEBRA,
66342 + vtysh_no_tunnel_cmd,
66343 + "no create tunnel IFNAME",
66344 + NO_STR
66345 + "Delete a virtual interface\n"
66346 + "Delete a tunnel interface\n"
66347 + "Interface's name\n")
66349 DEFUNSH (VTYSH_INTERFACE,
66350 vtysh_interface,
66351 vtysh_interface_cmd,
66352 @@ -2224,7 +2387,12 @@
66353 /* Install nodes. */
66354 install_node (&bgp_node, NULL);
66355 install_node (&rip_node, NULL);
66356 + install_node (&mpls_ldp_node, NULL);
66357 + install_node (&mpls_static_node, NULL);
66358 + install_node (&tunnel_node, NULL);
66359 + install_node (&mpls_tunnel_node, NULL);
66360 install_node (&interface_node, NULL);
66361 + install_node (&ldp_if_node, NULL);
66362 install_node (&rmap_node, NULL);
66363 install_node (&zebra_node, NULL);
66364 install_node (&bgp_vpnv4_node, NULL);
66365 @@ -2249,6 +2417,11 @@
66366 vtysh_install_default (CONFIG_NODE);
66367 vtysh_install_default (BGP_NODE);
66368 vtysh_install_default (RIP_NODE);
66369 + vtysh_install_default (LDP_NODE);
66370 + vtysh_install_default (LDP_IF_NODE);
66371 + vtysh_install_default (MPLS_LABELSPACE_NODE);
66372 + vtysh_install_default (TUNNEL_NODE);
66373 + vtysh_install_default (MPLS_TUNNEL_NODE);
66374 vtysh_install_default (INTERFACE_NODE);
66375 vtysh_install_default (RMAP_NODE);
66376 vtysh_install_default (ZEBRA_NODE);
66377 @@ -2276,6 +2449,16 @@
66378 /* install_element (CONFIG_NODE, &vtysh_quit_all_cmd); */
66379 install_element (ENABLE_NODE, &vtysh_exit_all_cmd);
66380 install_element (ENABLE_NODE, &vtysh_quit_all_cmd);
66381 + install_element (TUNNEL_NODE, &vtysh_exit_tunnel_cmd);
66382 + install_element (TUNNEL_NODE, &vtysh_quit_tunnel_cmd);
66383 + install_element (MPLS_TUNNEL_NODE, &vtysh_exit_tunnel_cmd);
66384 + install_element (MPLS_TUNNEL_NODE, &vtysh_quit_tunnel_cmd);
66385 + install_element (MPLS_LABELSPACE_NODE, &vtysh_exit_mpls_ls_cmd);
66386 + install_element (MPLS_LABELSPACE_NODE, &vtysh_quit_mpls_ls_cmd);
66387 + install_element (LDP_NODE, &vtysh_exit_ldpd_cmd);
66388 + install_element (LDP_NODE, &vtysh_quit_ldpd_cmd);
66389 + install_element (LDP_IF_NODE, &vtysh_exit_ldpd_cmd);
66390 + install_element (LDP_IF_NODE, &vtysh_quit_ldpd_cmd);
66391 install_element (RIP_NODE, &vtysh_exit_ripd_cmd);
66392 install_element (RIP_NODE, &vtysh_quit_ripd_cmd);
66393 install_element (RIPNG_NODE, &vtysh_exit_ripngd_cmd);
66394 @@ -2310,6 +2493,9 @@
66395 /* "end" command. */
66396 install_element (CONFIG_NODE, &vtysh_end_all_cmd);
66397 install_element (ENABLE_NODE, &vtysh_end_all_cmd);
66398 + install_element (MPLS_LABELSPACE_NODE, &vtysh_end_all_cmd);
66399 + install_element (LDP_NODE, &vtysh_end_all_cmd);
66400 + install_element (LDP_IF_NODE, &vtysh_end_all_cmd);
66401 install_element (RIP_NODE, &vtysh_end_all_cmd);
66402 install_element (RIPNG_NODE, &vtysh_end_all_cmd);
66403 install_element (OSPF_NODE, &vtysh_end_all_cmd);
66404 @@ -2325,12 +2511,17 @@
66405 install_element (KEYCHAIN_KEY_NODE, &vtysh_end_all_cmd);
66406 install_element (RMAP_NODE, &vtysh_end_all_cmd);
66407 install_element (VTY_NODE, &vtysh_end_all_cmd);
66408 + install_element (TUNNEL_NODE, &vtysh_end_all_cmd);
66409 + install_element (MPLS_TUNNEL_NODE, &vtysh_end_all_cmd);
66411 install_element (INTERFACE_NODE, &interface_desc_cmd);
66412 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
66413 install_element (INTERFACE_NODE, &vtysh_end_all_cmd);
66414 install_element (INTERFACE_NODE, &vtysh_exit_interface_cmd);
66415 install_element (INTERFACE_NODE, &vtysh_quit_interface_cmd);
66416 + install_element (INTERFACE_NODE, &vtysh_mpls_ip_cmd);
66417 + install_element (CONFIG_NODE, &mpls_static_cmd);
66418 + install_element (CONFIG_NODE, &vtysh_mpls_ldp_cmd);
66419 install_element (CONFIG_NODE, &router_rip_cmd);
66420 #ifdef HAVE_IPV6
66421 install_element (CONFIG_NODE, &router_ripng_cmd);
66422 @@ -2360,6 +2551,10 @@
66423 install_element (KEYCHAIN_NODE, &key_cmd);
66424 install_element (KEYCHAIN_NODE, &key_chain_cmd);
66425 install_element (KEYCHAIN_KEY_NODE, &key_chain_cmd);
66426 + install_element (CONFIG_NODE, &vtysh_tunnel_cmd);
66427 + install_element (TUNNEL_NODE, &vtysh_tunnel_mode_mpls_cmd);
66428 + install_element (MPLS_TUNNEL_NODE, &vtysh_tunnel_mode_mpls_cmd);
66429 + install_element (CONFIG_NODE, &vtysh_no_tunnel_cmd);
66430 install_element (CONFIG_NODE, &vtysh_interface_cmd);
66431 install_element (CONFIG_NODE, &vtysh_no_interface_cmd);
66432 install_element (ENABLE_NODE, &vtysh_show_running_config_cmd);
66433 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/vtysh/vtysh_config.c quagga-mpls/vtysh/vtysh_config.c
66434 --- quagga/vtysh/vtysh_config.c 2005-04-05 04:07:20.000000000 -0500
66435 +++ quagga-mpls/vtysh/vtysh_config.c 2006-12-04 22:47:24.000000000 -0600
66436 @@ -190,6 +190,8 @@
66437 config = config_get (INTERFACE_NODE, line);
66438 else if (strncmp (line, "router-id", strlen ("router-id")) == 0)
66439 config = config_get (ZEBRA_NODE, line);
66440 + else if (strncmp(line, "mpls static", strlen("mpls static")) == 0)
66441 + config = config_get (MPLS_LABELSPACE_NODE, line);
66442 else if (strncmp (line, "router rip", strlen ("router rip")) == 0)
66443 config = config_get (RIP_NODE, line);
66444 else if (strncmp (line, "router ripng", strlen ("router ripng")) == 0)
66445 @@ -204,6 +206,8 @@
66446 config = config_get (ISIS_NODE, line);
66447 else if (strncmp (line, "router bgp", strlen ("router bgp")) == 0)
66448 config = config_get (BGP_NODE, line);
66449 + else if (strncmp (line, "mpls ldp", strlen ("mpls ldp")) == 0)
66450 + config = config_get (LDP_NODE, line);
66451 else if (strncmp (line, "route-map", strlen ("route-map")) == 0)
66452 config = config_get (RMAP_NODE, line);
66453 else if (strncmp (line, "access-list", strlen ("access-list")) == 0)
66454 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/vtysh/vtysh.h quagga-mpls/vtysh/vtysh.h
66455 --- quagga/vtysh/vtysh.h 2007-05-02 10:28:33.000000000 -0500
66456 +++ quagga-mpls/vtysh/vtysh.h 2008-02-19 23:05:57.000000000 -0600
66457 @@ -29,9 +29,10 @@
66458 #define VTYSH_OSPF6D 0x10
66459 #define VTYSH_BGPD 0x20
66460 #define VTYSH_ISISD 0x40
66461 -#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD
66462 +#define VTYSH_LDPD 0x80
66463 +#define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_LDPD
66464 #define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD
66465 -#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD
66466 +#define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_LDPD
66468 /* vtysh local configuration file. */
66469 #define VTYSH_DEFAULT_CONFIG "vtysh.conf"
66470 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/connected.c quagga-mpls/zebra/connected.c
66471 --- quagga/zebra/connected.c 2008-09-04 20:37:37.000000000 -0500
66472 +++ quagga-mpls/zebra/connected.c 2008-09-07 20:23:36.000000000 -0500
66473 @@ -174,6 +174,7 @@
66474 connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
66476 struct prefix_ipv4 p;
66477 + struct zapi_nexthop nh;
66479 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
66480 return;
66481 @@ -188,8 +189,12 @@
66482 if (prefix_ipv4_any (&p))
66483 return;
66485 - rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex,
66486 - RT_TABLE_MAIN, ifp->metric, 0);
66487 + memset (&nh, 0, sizeof (struct zapi_nexthop));
66488 + SET_FLAG(nh.type, ZEBRA_NEXTHOP_IFINDEX);
66489 + nh.intf.index = ifp->ifindex;
66491 + rib_add_route (ZEBRA_ROUTE_CONNECT, 0, (struct prefix*)&p,
66492 + &nh, RT_TABLE_MAIN, ifp->metric, 0);
66494 rib_update ();
66496 @@ -280,6 +285,7 @@
66497 connected_down_ipv4 (struct interface *ifp, struct connected *ifc)
66499 struct prefix_ipv4 p;
66500 + struct zapi_nexthop nh;
66502 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
66503 return;
66504 @@ -294,8 +300,11 @@
66505 if (prefix_ipv4_any (&p))
66506 return;
66508 - /* Same logic as for connected_up_ipv4(): push the changes into the head. */
66509 - rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0);
66510 + memset (&nh, 0, sizeof (struct zapi_nexthop));
66511 + SET_FLAG (nh.type, ZEBRA_NEXTHOP_IFINDEX);
66512 + nh.intf.index = ifp->ifindex;
66514 + rib_delete_route (ZEBRA_ROUTE_CONNECT, 0, (struct prefix*)&p, &nh, 0);
66516 rib_update ();
66518 @@ -325,6 +334,7 @@
66519 connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
66521 struct prefix_ipv6 p;
66522 + struct zapi_nexthop nh;
66524 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
66525 return;
66526 @@ -335,13 +345,17 @@
66527 apply_mask_ipv6 (&p);
66529 #if ! defined (MUSICA) && ! defined (LINUX)
66530 - /* XXX: It is already done by rib_bogus_ipv6 within rib_add_ipv6 */
66531 + /* XXX: It is already done by rib_bogus_ipv6 within rib_add_route */
66532 if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
66533 return;
66534 #endif
66536 - rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0,
66537 - ifp->metric, 0);
66538 + memset (&nh, 0, sizeof (struct zapi_nexthop));
66539 + SET_FLAG (nh.type, ZEBRA_NEXTHOP_IFINDEX);
66540 + nh.intf.index = ifp->ifindex;
66542 + rib_add_route (ZEBRA_ROUTE_CONNECT, 0, (struct prefix*)&p,
66543 + &nh, 0, ifp->metric, 0);
66545 rib_update ();
66547 @@ -404,6 +418,7 @@
66548 connected_down_ipv6 (struct interface *ifp, struct connected *ifc)
66550 struct prefix_ipv6 p;
66551 + struct zapi_nexthop nh;
66553 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
66554 return;
66555 @@ -415,7 +430,11 @@
66556 if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
66557 return;
66559 - rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0);
66560 + memset (&nh, 0, sizeof (struct zapi_nexthop));
66561 + SET_FLAG (nh.type, ZEBRA_NEXTHOP_IFINDEX);
66562 + nh.intf.index = ifp->ifindex;
66564 + rib_delete_route (ZEBRA_ROUTE_CONNECT, 0, (struct prefix*)&p, &nh, 0);
66566 rib_update ();
66568 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/if_netlink.c quagga-mpls/zebra/if_netlink.c
66569 --- quagga/zebra/if_netlink.c 2002-12-13 14:15:30.000000000 -0600
66570 +++ quagga-mpls/zebra/if_netlink.c 2006-08-09 22:03:17.000000000 -0500
66571 @@ -22,8 +22,7 @@
66573 #include <zebra.h>
66575 -/* Extern from rt_netlink.c */
66576 -void interface_lookup_netlink ();
66577 +#include "zebra/rt_netlink.h"
66579 /* Interface information read by netlink. */
66580 void
66581 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/if_tunnel.c quagga-mpls/zebra/if_tunnel.c
66582 --- quagga/zebra/if_tunnel.c 1969-12-31 18:00:00.000000000 -0600
66583 +++ quagga-mpls/zebra/if_tunnel.c 2008-02-22 22:00:03.000000000 -0600
66584 @@ -0,0 +1,862 @@
66585 +/* Zebra Tunnel VTY functions
66586 + * Copyright (C) 2005 James R. Leu
66588 + * This file is part of GNU Zebra.
66590 + * GNU Zebra is free software; you can redistribute it and/or modify it
66591 + * under the terms of the GNU General Public License as published by the
66592 + * Free Software Foundation; either version 2, or (at your option) any
66593 + * later version.
66595 + * GNU Zebra is distributed in the hope that it will be useful, but
66596 + * WITHOUT ANY WARRANTY; without even the implied warranty of
66597 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
66598 + * General Public License for more details.
66600 + * You should have received a copy of the GNU General Public License
66601 + * along with GNU Zebra; see the file COPYING. If not, write to the
66602 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
66603 + * Boston, MA 02111-1307, USA.
66604 + */
66606 +#include <stdio.h>
66607 +#include <stdlib.h>
66608 +#include <string.h>
66609 +#include <unistd.h>
66610 +#include <sys/types.h>
66611 +#include <sys/socket.h>
66612 +#include <sys/ioctl.h>
66613 +#include <net/if.h>
66614 +/* #include <linux/if.h>
66615 +#include <arpa/inet.h>
66616 +#include <linux/if_arp.h> */
66617 +#include <netinet/ip.h>
66618 +#include <linux/if_tunnel.h>
66619 +#include <linux/sockios.h>
66621 +#include <zebra.h>
66623 +#include "if.h"
66624 +#include "memory.h"
66625 +#include "memory.h"
66626 +#include "command.h"
66627 +#include "vty.h"
66628 +#include "prefix.h"
66629 +#include "table.h"
66630 +#include "interface.h"
66631 +#ifdef HAVE_MPLS
66632 +#include "mpls_vty.h"
66633 +#endif
66634 +#include "ioctl.h"
66636 +enum tunnel_type
66638 + TUNNEL_GRE = 1,
66639 + TUNNEL_IPIP,
66640 + TUNNEL_SIT,
66641 + TUNNEL_MPLS,
66642 + TUNNEL_MAX,
66645 +struct tunnel_info
66647 + enum tunnel_type type;
66648 + struct prefix dest;
66649 + int configured;
66650 + int (*action)(int, struct interface*);
66651 + int (*check)(int, struct interface*);
66652 + void *data;
66655 +static const char*
66656 +tunnel_mode_str (int type)
66658 + const char *mode;
66659 + switch (type)
66661 + case TUNNEL_GRE:
66662 + mode = "gre";
66663 + break;
66664 + case TUNNEL_IPIP:
66665 + mode = "ipip";
66666 + break;
66667 + case TUNNEL_SIT:
66668 + mode = "sit";
66669 + break;
66670 +#ifdef HAVE_MPLS
66671 + case TUNNEL_MPLS:
66672 + mode = "mpls";
66673 + break;
66674 +#endif
66675 + default:
66676 + assert (0);
66677 + break;
66679 + return mode;
66682 +static void
66683 +tunnel_config (struct vty *vty, struct interface *ifp)
66685 + struct zebra_if *if_data = ifp->info;
66686 + struct tunnel_info *tun_data = if_data->ops->info;
66687 + char buf[BUFSIZ];
66689 + vty_out (vty, "create tunnel %s%s", ifp->name, VTY_NEWLINE);
66690 + prefix2str (&tun_data->dest, buf, sizeof (buf));
66691 + vty_out (vty, " tunnel dest %s%s", buf, VTY_NEWLINE);
66692 + vty_out (vty, " tunnel mode %s%s", tunnel_mode_str (tun_data->type),
66693 + VTY_NEWLINE);
66696 +static void
66697 +tunnel_show (struct vty *vty, struct interface *ifp)
66699 + struct zebra_if *if_data = ifp->info;
66700 + struct tunnel_info *tun_data = if_data->ops->info;
66701 + char buf[BUFSIZ];
66703 + prefix2str (&tun_data->dest, buf, sizeof (buf));
66705 + vty_out (vty, " Tunnel mode: %s Destination: %s%s",
66706 + tunnel_mode_str (tun_data->type), buf, VTY_NEWLINE);
66709 +static void
66710 +tunnel_free (struct interface *ifp)
66712 + struct zebra_if *if_data = ifp->info;
66713 + XFREE (MTYPE_TMP, if_data->ops);
66714 + if_data->ops = NULL;
66717 +static int
66718 +do_tunnel (int cmd, struct interface *ifp)
66720 + struct ip_tunnel_parm args;
66721 + struct ifreq ifr;
66722 + struct zebra_if *if_data = ifp->info;
66723 + struct tunnel_info *tun_data = if_data->ops->info;
66725 + memset(&args, 0, sizeof(args));
66726 + strncpy(args.name, ifp->name, IFNAMSIZ);
66727 + args.iph.version = 4;
66728 + args.iph.ihl = 5;
66729 + args.iph.frag_off = htons(IP_DF);
66730 + args.iph.daddr = tun_data->dest.u.prefix4.s_addr;
66732 + switch (tun_data->type)
66734 + case TUNNEL_GRE:
66735 + args.iph.protocol = IPPROTO_GRE;
66736 + strcpy(ifr.ifr_name, "gre0");
66737 + break;
66738 + case TUNNEL_IPIP:
66739 + args.iph.protocol = IPPROTO_IPIP;
66740 + strcpy(ifr.ifr_name, "tunl0");
66741 + break;
66742 + case TUNNEL_SIT:
66743 + args.iph.protocol = IPPROTO_IPV6;
66744 + strcpy(ifr.ifr_name, "sit0");
66745 + break;
66746 + default:
66747 + assert (0);
66750 + ifr.ifr_ifru.ifru_data = (void*)&args;
66751 + return if_ioctl(cmd, (caddr_t)&ifr);
66754 +static int
66755 +do_tunnel_check (int cmd, struct interface *ifp)
66757 + struct zebra_if *if_data = ifp->info;
66758 + struct tunnel_info *tun_data = if_data->ops->info;
66760 + if (cmd == SIOCADDTUNNEL)
66762 + if ((!tun_data->configured) && tun_data->type &&
66763 + tun_data->dest.family && tun_data->data)
66764 + return 1;
66766 + else
66768 + if (tun_data->configured)
66769 + return 1;
66771 + return 0;
66774 +#ifdef LINUX_MPLS
66775 +static int
66776 +do_mpls_tunnel (int cmd, struct interface *ifp)
66778 + struct mpls_tunnel_req mtr;
66779 + struct ifreq ifr;
66780 + struct zebra_if *if_data = ifp->info;
66781 + struct tunnel_info *tun_data = if_data->ops->info;
66782 + struct zmpls_out_segment *out = tun_data->data;
66784 + memset(&mtr, 0, sizeof(mtr));
66785 + strncpy(mtr.mt_ifname, ifp->name, IFNAMSIZ);
66786 + strcpy(ifr.ifr_name, "mpls0");
66787 + mtr.mt_nhlfe_key = out->out_key;
66789 + ifr.ifr_ifru.ifru_data = (void*)&mtr;
66790 + return if_ioctl(cmd, (caddr_t)&ifr);
66792 +#if 0
66794 + ADD
66796 + struct interface *ifp;
66797 + struct connected *ifc;
66798 + struct prefix dest;
66799 + struct prefix *p;
66800 + int ret;
66802 + if (listcount (ifp->connected))
66804 + vty_out (vty, "%% Tunnel destination already configured %s", VTY_NEWLINE);
66805 + return CMD_WARNING;
66808 + ifc = connected_new ();
66809 + ifc->ifp = ifp;
66811 + /* source */
66812 + p = prefix_new ();
66813 + router_id_get (p);
66814 + ifc->address = (struct prefix *) p;
66816 + /* destination. */
66817 + p = prefix_new ();
66818 + *p = dest;
66819 + p->prefixlen = (p->family == AF_INET)?IPV4_MAX_BITLEN:IPV6_MAX_PREFIXLEN;
66820 + ifc->destination = (struct prefix *) p;
66822 + /* Add to linked list. */
66823 + listnode_add (ifp->connected, ifc);
66825 + SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED);
66827 + if_set_flags (ifp, IFF_UP | IFF_RUNNING);
66828 + if_refresh (ifp);
66830 + ret = if_set_prefix (ifp, ifc);
66831 + if (ret < 0)
66833 + vty_out (vty, "%% Can't set interface IP address: %s.%s",
66834 + strerror(errno), VTY_NEWLINE);
66835 + return CMD_WARNING;
66838 + /* IP address propery set. */
66839 + SET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
66841 + /* Update interface address information to protocol daemon. */
66842 + zebra_interface_address_add_update (ifp, ifc);
66844 + /* If interface is up register connected route. */
66845 + if (if_is_operative(ifp))
66846 + connected_up_ipv4 (ifp, ifc);
66848 + mpls_ctrl_tunnel_register(ifp, 1);
66851 + DEL
66853 + struct interface *ifp;
66854 + struct connected *ifc;
66855 + int ret;
66857 + ifp = (struct interface *) vty->index;
66858 + ifc = listgetdata (listhead (ifp->connected));
66860 + /* This is real route. */
66861 + ret = if_unset_prefix (ifp, ifc);
66862 + if (ret < 0)
66864 + vty_out (vty, "%% Can't unset interface IP address: %s.%s",
66865 + strerror(errno), VTY_NEWLINE);
66866 + return CMD_WARNING;
66869 + /* Redistribute this information. */
66870 + zebra_interface_address_delete_update (ifp, ifc);
66872 + /* Remove connected route. */
66873 + connected_down_ipv4 (ifp, ifc);
66875 + /* Free address information. */
66876 + listnode_delete (ifp->connected, ifc);
66877 + connected_free (ifc);
66879 + mpls_ctrl_tunnel_unregister(ifp, 1);
66881 +static void
66882 +mpls_interface_config_write (struct vty *vty, struct interface *ifp)
66884 + struct zebra_if *if_data;
66885 + if_data = ifp->info;
66887 + vty_out (vty, "create mpls-tunnel %s%s", ifp->name, VTY_NEWLINE);
66889 + if (if_data && if_data->ops && if_data->ops->info)
66891 + struct zmpls_out_segment *out;
66893 + out = mpls_out_segment_find_by_out_key((int)if_data->ops->info);
66894 + if (out)
66896 + vty_out (vty, " tunnel mode mpls static ");
66897 + mpls_out_segment_config_write (vty, out);
66898 + vty_out (vty, "%s", VTY_NEWLINE);
66904 +#endif
66907 +static int
66908 +do_mpls_tunnel_check (int cmd, struct interface *ifp)
66910 + struct zebra_if *if_data = ifp->info;
66911 + struct tunnel_info *tun_data = if_data->ops->info;
66913 + if (cmd == SIOCADDTUNNEL)
66915 + if ((!tun_data->configured) && tun_data->type && tun_data->dest.family)
66916 + return 1;
66918 + else
66920 + if (tun_data->configured)
66921 + return 1;
66923 + return 0;
66925 +#endif
66927 +static int
66928 +tunnel_create_check (struct interface *ifp)
66930 + struct zebra_if *if_data = ifp->info;
66931 + struct tunnel_info *tun_data = if_data->ops->info;
66932 + return tun_data->check(SIOCDELTUNNEL, ifp);
66935 +static int
66936 +tunnel_delete_check (struct interface *ifp)
66938 + struct zebra_if *if_data = ifp->info;
66939 + struct tunnel_info *tun_data = if_data->ops->info;
66940 + return tun_data->check(SIOCDELTUNNEL, ifp);
66943 +static int
66944 +tunnel_create (struct interface *ifp)
66946 + struct zebra_if *if_data = ifp->info;
66947 + struct tunnel_info *tun_data = if_data->ops->info;
66948 + int ret = tun_data->action (SIOCADDTUNNEL, ifp);
66949 + if (!ret)
66950 + tun_data->configured = 1;
66951 + return ret;
66954 +static int
66955 +tunnel_delete (struct interface *ifp)
66957 + struct zebra_if *if_data = ifp->info;
66958 + struct tunnel_info *tun_data = if_data->ops->info;
66959 + int ret = tun_data->action (SIOCADDTUNNEL, ifp);
66960 + tun_data->configured = 0;
66961 + return ret;
66964 +static struct interface_ops*
66965 +tunnel_create_ops ()
66967 + struct tunnel_info *tun_data;
66968 + struct interface_ops *ops = XMALLOC (MTYPE_TMP,
66969 + sizeof(struct interface_ops) + sizeof (struct tunnel_info));
66971 + if (!ops)
66972 + return NULL;
66974 + memset (ops, 0, sizeof(struct interface_ops));
66975 + ops->type = INTERFACE_TYPE_TUNNEL;
66976 + ops->config = &tunnel_config;
66977 + ops->show = &tunnel_show;
66978 + ops->create_check = &tunnel_create_check;
66979 + ops->delete_check = &tunnel_delete_check;
66980 + ops->create = &tunnel_create;
66981 + ops->delete = &tunnel_delete;
66982 + ops->free = &tunnel_free;
66983 + ops->info = &ops[1];
66985 + tun_data = ops->info;
66986 + tun_data->action = &do_tunnel;
66987 + tun_data->check = &do_tunnel_check;
66989 + return ops;
66992 +DEFUN (create_tunnel,
66993 + create_tunnel_cmd,
66994 + "create tunnel IFNAME",
66995 + "Create virtual interface\n"
66996 + "Create tunnel interface\n"
66997 + "Tunnel interface name\n")
66999 + struct zebra_if *if_data;
67000 + struct interface *ifp;
67002 + ifp = if_lookup_by_name(argv[0]);
67003 + if (!ifp)
67005 + ifp = if_create (argv[0], strlen (argv[0]));
67006 + if (!ifp)
67008 + vty_out (vty, "%% Unable to create tunnel%s", VTY_NEWLINE);
67009 + return CMD_WARNING;
67013 + if_data = ifp->info;
67014 + if (if_data->ops)
67016 + if (if_data->ops->type != INTERFACE_TYPE_TUNNEL)
67018 + vty_out (vty, "%% Interface is already owned by a protocol other then tunnel%s", VTY_NEWLINE);
67019 + return CMD_WARNING;
67022 + else
67024 + if_data->ops = tunnel_create_ops();
67025 + if (!if_data->ops)
67027 + vty_out (vty, "%% Unable to create tunnel%s", VTY_NEWLINE);
67028 + return CMD_WARNING;
67032 + vty->index = ifp;
67033 + vty->node = TUNNEL_NODE;
67035 + return CMD_SUCCESS;
67038 +DEFUN (no_create_tunnel,
67039 + no_create_tunnel_cmd,
67040 + "no create tunnel IFNAME",
67041 + NO_STR
67042 + "Delete virtual interface\n"
67043 + "Delete tunnel interface\n"
67044 + "Tunnel interface name\n")
67046 + struct zebra_if *if_data;
67047 + struct interface *ifp;
67049 + ifp = if_lookup_by_name (argv[0]);
67050 + if (!ifp)
67052 + vty_out (vty, "%% No such tunnel interface%s", VTY_NEWLINE);
67053 + return CMD_WARNING;
67056 + if_data = ifp->info;
67057 + if (if_data && if_data->ops && if_data->ops->type == INTERFACE_TYPE_TUNNEL)
67059 + struct tunnel_info *tun_data = if_data->ops->info;
67061 + if (tun_data->configured)
67062 + if_data->ops->delete (ifp);
67064 + if_zebra_delete_ops (ifp);
67066 + else
67068 + vty_out (vty, "%% Interface is not a tunnel interface%s", VTY_NEWLINE);
67069 + return CMD_WARNING;
67072 + return CMD_SUCCESS;
67075 +DEFUN (tunnel_destination,
67076 + tunnel_destination_cmd,
67077 + "tunnel destination IPADDR",
67078 + "Tunnel configuration\n"
67079 + "Destination of tunnel\n"
67080 + "IP Address of the destination of tunnel\n")
67082 + struct interface *ifp = (struct interface *) vty->index;
67083 + struct zebra_if *if_data = ifp->info;
67084 + struct tunnel_info *tun_data = if_data->ops->info;
67085 + int ret;
67087 + ret = str2prefix (argv[0], &tun_data->dest);
67088 + if (ret <= 0)
67090 + vty_out (vty, "%% Malformed destination address %s", VTY_NEWLINE);
67091 + return CMD_WARNING;
67094 + if (if_data->ops->create_check (ifp))
67095 + if (if_data->ops->create (ifp) < 0)
67097 + vty_out (vty, "%% Unable to create tunnel%s", VTY_NEWLINE);
67098 + return CMD_WARNING;
67101 + return CMD_SUCCESS;
67104 +DEFUN (no_tunnel_destination,
67105 + no_tunnel_destination_cmd,
67106 + "no tunnel destination",
67107 + NO_STR
67108 + "Tunnel configuration\n"
67109 + "Destination of tunnel\n")
67111 + struct interface *ifp = (struct interface *) vty->index;
67112 + struct zebra_if *if_data = ifp->info;
67113 + struct tunnel_info *tun_data = if_data->ops->info;
67115 + if (if_data->ops->delete_check(ifp))
67116 + if_data->ops->delete (ifp);
67118 + memset(&tun_data->dest, 0, sizeof (struct prefix));
67120 + return CMD_SUCCESS;
67123 +DEFUN (tunnel_mode,
67124 + tunnel_mode_cmd,
67125 + "tunnel mode (gre|sit|ipip)",
67126 + "Tunnel configuration\n"
67127 + "Tunnel mode configuration\n"
67128 + "Generic Routing Encapsulation\n"
67129 + "IPv6 in IPv4\n"
67130 + "IPv4 in IPv4\n")
67132 + struct interface *ifp = (struct interface *) vty->index;
67133 + struct zebra_if *if_data = ifp->info;
67134 + struct tunnel_info *tun_data = if_data->ops->info;
67135 + int new_type = 0;
67137 + if (strncmp(argv[0], "gre", 3) == 0) {
67138 + new_type = TUNNEL_GRE;
67139 + } else if (strncmp(argv[0], "sit", 3) == 0) {
67140 + new_type = TUNNEL_SIT;
67141 + } else if (strncmp(argv[0], "ipip", 4) == 0) {
67142 + new_type = TUNNEL_IPIP;
67143 + } else {
67144 + vty_out (vty, "%% Unknown tunnel mode%s\n", VTY_NEWLINE);
67145 + return CMD_WARNING;
67148 + if (tun_data->type != new_type)
67150 + if (if_data->ops->delete_check (ifp))
67151 + if_data->ops->delete (ifp);
67153 + tun_data->type = new_type;
67154 + vty->node = TUNNEL_NODE;
67156 + tun_data->action = &do_tunnel;
67157 + tun_data->check = &do_tunnel_check;
67160 + if (if_data->ops->create_check (ifp))
67161 + if (if_data->ops->create (ifp) < 0)
67163 + vty_out (vty, "%% Unable to create tunnel%s", VTY_NEWLINE);
67164 + return CMD_WARNING;
67167 + return CMD_SUCCESS;
67170 +DEFUN (no_tunnel_mode,
67171 + no_tunnel_mode_cmd,
67172 + "no tunnel mode",
67173 + NO_STR
67174 + "Tunnel configuration\n"
67175 + "Tunnel mode configuration\n")
67177 + struct interface *ifp = (struct interface *) vty->index;
67178 + struct zebra_if *if_data = ifp->info;
67179 + struct tunnel_info *tun_data = if_data->ops->info;
67181 + if (if_data->ops->delete_check(ifp))
67182 + if_data->ops->delete (ifp);
67184 + tun_data->type = 0;
67185 + tun_data->action = &do_tunnel;
67186 + tun_data->check = &do_tunnel_check;
67188 + return CMD_SUCCESS;
67191 +#ifdef LINUX_MPLS
67192 +DEFUN (tunnel_mode_mpls,
67193 + tunnel_mode_mpls_cmd,
67194 + "tunnel mode mpls",
67195 + "Tunnel configuration\n"
67196 + "Tunnel mode configuration\n"
67197 + "MPLS\n")
67199 + struct interface *ifp = (struct interface *) vty->index;
67200 + struct zebra_if *if_data = ifp->info;
67201 + struct tunnel_info *tun_data = if_data->ops->info;
67203 + if (tun_data->type != TUNNEL_MPLS)
67205 + if (if_data->ops->delete_check (ifp))
67206 + if_data->ops->delete (ifp);
67208 + tun_data->type = TUNNEL_MPLS;
67209 + vty->node = MPLS_TUNNEL_NODE;
67211 + tun_data->action = &do_mpls_tunnel;
67212 + tun_data->check = &do_mpls_tunnel_check;
67215 + if (if_data->ops->create_check (ifp))
67216 + if (if_data->ops->create (ifp) < 0)
67218 + vty_out (vty, "%% Unable to create tunnel%s", VTY_NEWLINE);
67219 + return CMD_WARNING;
67222 + return CMD_SUCCESS;
67225 +static int
67226 +mpls_static(struct vty *vty, struct zmpls_out_segment *new, struct interface *ifp)
67228 + struct zebra_if *if_data = ifp->info;
67229 + struct tunnel_info *tun_data = if_data->ops->info;
67230 + struct zmpls_out_segment *out = NULL;
67231 + int index;
67233 + if (tun_data->data)
67235 + return CMD_WARNING;
67238 + if (mpls_out_segment_register(new))
67240 + return CMD_WARNING;
67243 + index = mpls_out_segment_find_index_by_nhlfe(new);
67244 + assert(index);
67245 + tun_data->data = mpls_out_segment_find(index);
67247 + if (if_data->ops->create_check (ifp))
67248 + if (if_data->ops->create (ifp) < 0)
67250 + vty_out (vty, "%% Unable to create tunnel%s", VTY_NEWLINE);
67251 + return CMD_WARNING;
67254 + return CMD_SUCCESS;
67257 +DEFUN (tunnel_mpls_static_addr,
67258 + tunnel_mpls_static_addr_cmd,
67259 + "tunnel mpls static (gen|atm|fr) VALUE nexthop INTERFACE ADDR",
67260 + "Tunnel configuration\n"
67261 + "MPLS Tunnel configuration\n"
67262 + "Static Tunnel Configuration\n"
67263 + "Out-going generic MPLS label (16 - 2^20-1)\n"
67264 + "Out-going ATM MPLS label (VPI/VCI)\n"
67265 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
67266 + "Out-going label value\n"
67267 + "Nexthop\n"
67268 + "IP gateway interface name\n"
67269 + "IP gateway address\n")
67271 + struct interface *ifp = (struct interface *) vty->index;
67272 + struct zmpls_out_segment new;
67273 + int result;
67275 + memset (&new, 0, sizeof (new));
67276 + new.owner = ZEBRA_ROUTE_STATIC;
67277 + result = nhlfe_parse (vty, &argv[0], &new, argv[3]);
67278 + if (result != CMD_SUCCESS)
67279 + return result;
67281 + return mpls_static(vty, &new, ifp);
67284 +DEFUN (tunnel_mpls_static_intf,
67285 + tunnel_mpls_static_intf_cmd,
67286 + "tunnel mpls static (gen|atm|fr) VALUE nexthop INTERFACE",
67287 + "Tunnel configuration\n"
67288 + "MPLS Tunnel configuration\n"
67289 + "Static Tunnel Configuration\n"
67290 + "Out-going generic MPLS label (16 - 2^20-1)\n"
67291 + "Out-going ATM MPLS label (VPI/VCI)\n"
67292 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
67293 + "Out-going label value\n"
67294 + "Nexthop\n"
67295 + "IP gateway interface name\n")
67297 + struct interface *ifp = (struct interface *) vty->index;
67298 + struct zmpls_out_segment new;
67299 + int result;
67301 + memset (&new, 0, sizeof (new));
67302 + new.owner = ZEBRA_ROUTE_STATIC;
67303 + result = nhlfe_parse (vty, &argv[0], &new, NULL);
67304 + if (result != CMD_SUCCESS)
67305 + return result;
67307 + return mpls_static(vty, &new, ifp);
67310 +static int
67311 +no_mpls_static(struct vty *vty, struct zmpls_out_segment *old, struct interface *ifp)
67313 + struct zebra_if *if_data = ifp->info;
67314 + struct tunnel_info *tun_data = if_data->ops->info;
67315 + struct zmpls_out_segment *out = tun_data->data;
67316 + struct zmpls_out_segment *tmp;
67317 + int index;
67319 + if (!out)
67321 + return CMD_WARNING;
67324 + index = mpls_out_segment_find_index_by_nhlfe(old);
67325 + if (!index)
67327 + return CMD_WARNING;
67330 + tmp = mpls_out_segment_find(index);
67331 + if (tmp->index != out->index)
67333 + return CMD_WARNING;
67336 + if (if_data->ops->delete_check(ifp))
67337 + if_data->ops->delete (ifp);
67339 + mpls_out_segment_unregister (out);
67340 + tun_data->data = NULL;
67342 + return CMD_SUCCESS;
67345 +DEFUN (no_tunnel_mpls_static_addr,
67346 + no_tunnel_mpls_static_addr_cmd,
67347 + "no tunnel mpls static (gen|atm|fr) VALUE nexthop INTERFACE ADDR",
67348 + NO_STR
67349 + "Tunnel configuration\n"
67350 + "MPLS Tunnel configuration\n"
67351 + "Static Tunnel Configuration\n"
67352 + "Out-going generic MPLS label (16 - 2^20-1)\n"
67353 + "Out-going ATM MPLS label (VPI/VCI)\n"
67354 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
67355 + "Out-going label value\n"
67356 + "Nexthop\n"
67357 + "IP gateway interface name\n"
67358 + "IP gateway address\n")
67360 + struct interface *ifp = (struct interface *) vty->index;
67361 + struct zmpls_out_segment old;
67362 + int result;
67364 + memset (&old, 0, sizeof (old));
67365 + old.owner = ZEBRA_ROUTE_STATIC;
67366 + result = nhlfe_parse (vty, &argv[0], &old, argv[3]);
67367 + if (result != CMD_SUCCESS)
67368 + return result;
67370 + return no_mpls_static(vty, &old, ifp);
67373 +DEFUN (no_tunnel_mpls_static_intf,
67374 + no_tunnel_mpls_static_intf_cmd,
67375 + "no tunnel mpls static (gen|atm|fr) VALUE nexthop INTERFACE",
67376 + NO_STR
67377 + "Tunnel configuration\n"
67378 + "MPLS Tunnel configuration\n"
67379 + "Static Tunnel Configuration\n"
67380 + "Out-going generic MPLS label (16 - 2^20-1)\n"
67381 + "Out-going ATM MPLS label (VPI/VCI)\n"
67382 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
67383 + "Out-going label value\n"
67384 + "Nexthop\n"
67385 + "IP gateway interface name\n")
67387 + struct interface *ifp = (struct interface *) vty->index;
67388 + struct zmpls_out_segment old;
67389 + int result;
67391 + memset (&old, 0, sizeof (old));
67392 + old.owner = ZEBRA_ROUTE_STATIC;
67393 + result = nhlfe_parse (vty, &argv[0], &old, NULL);
67394 + if (result != CMD_SUCCESS)
67395 + return result;
67397 + return no_mpls_static(vty, &old, ifp);
67400 +struct cmd_node mpls_tunnel_node =
67402 + MPLS_TUNNEL_NODE,
67403 + "%s(config-tun-mpls)# ",
67406 +#endif
67408 +struct cmd_node tunnel_node =
67410 + TUNNEL_NODE,
67411 + "%s(config-tun)# ",
67415 +static int
67416 +tunnel_config_write (struct vty *vty)
67418 + return 0;
67421 +void
67422 +if_tunnel_init ()
67424 + install_element (CONFIG_NODE, &create_tunnel_cmd);
67425 + install_element (CONFIG_NODE, &no_create_tunnel_cmd);
67427 + install_node (&tunnel_node, tunnel_config_write);
67429 + install_element (TUNNEL_NODE, &tunnel_destination_cmd);
67430 + install_element (TUNNEL_NODE, &no_tunnel_destination_cmd);
67431 + install_element (TUNNEL_NODE, &tunnel_mode_cmd);
67432 + install_element (TUNNEL_NODE, &no_tunnel_mode_cmd);
67433 +#ifdef LINUX_MPLS
67434 + install_element (TUNNEL_NODE, &tunnel_mode_mpls_cmd);
67435 + install_node (&mpls_tunnel_node, tunnel_config_write);
67436 + install_element (MPLS_TUNNEL_NODE, &tunnel_destination_cmd);
67437 + install_element (MPLS_TUNNEL_NODE, &no_tunnel_destination_cmd);
67438 + install_element (MPLS_TUNNEL_NODE, &tunnel_mode_cmd);
67439 + install_element (MPLS_TUNNEL_NODE, &tunnel_mode_mpls_cmd);
67440 + install_element (MPLS_TUNNEL_NODE, &no_tunnel_mode_cmd);
67441 + install_element (MPLS_TUNNEL_NODE, &tunnel_mpls_static_addr_cmd);
67442 + install_element (MPLS_TUNNEL_NODE, &tunnel_mpls_static_intf_cmd);
67443 + install_element (MPLS_TUNNEL_NODE, &no_tunnel_mpls_static_addr_cmd);
67444 + install_element (MPLS_TUNNEL_NODE, &no_tunnel_mpls_static_intf_cmd);
67445 +#endif
67447 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/if_vlan.c quagga-mpls/zebra/if_vlan.c
67448 --- quagga/zebra/if_vlan.c 1969-12-31 18:00:00.000000000 -0600
67449 +++ quagga-mpls/zebra/if_vlan.c 2006-08-09 22:03:19.000000000 -0500
67450 @@ -0,0 +1,199 @@
67451 +/* Zebra VLAN VTY functions
67452 + * Copyright (C) 2005 James R. Leu
67454 + * This file is part of GNU Zebra.
67456 + * GNU Zebra is free software; you can redistribute it and/or modify it
67457 + * under the terms of the GNU General Public License as published by the
67458 + * Free Software Foundation; either version 2, or (at your option) any
67459 + * later version.
67461 + * GNU Zebra is distributed in the hope that it will be useful, but
67462 + * WITHOUT ANY WARRANTY; without even the implied warranty of
67463 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
67464 + * General Public License for more details.
67466 + * You should have received a copy of the GNU General Public License
67467 + * along with GNU Zebra; see the file COPYING. If not, write to the
67468 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
67469 + * Boston, MA 02111-1307, USA.
67470 + */
67472 +#include <zebra.h>
67474 +#include "if.h"
67475 +#include "memory.h"
67476 +#include "command.h"
67477 +#include "vty.h"
67478 +#include "prefix.h"
67479 +#include "table.h"
67480 +#include "interface.h"
67482 +#include <linux/if_vlan.h>
67483 +#include <linux/sockios.h>
67484 +#include "ioctl.h"
67486 +static void
67487 +vlan_config (struct vty *vty, struct interface *ifp)
67489 + vty_out (vty, "create vlan %s%s", ifp->name, VTY_NEWLINE);
67492 +static void
67493 +vlan_show (struct vty *vty, struct interface *ifp)
67495 + struct zebra_if *if_data;
67496 + if_data = ifp->info;
67497 + vty_out (vty, " 802.1q VLAN Tag %d%s", (int)if_data->ops->info, VTY_NEWLINE);
67500 +static void
67501 +vlan_free (struct interface *ifp)
67503 + struct zebra_if *if_data;
67504 + if_data = ifp->info;
67505 + XFREE (MTYPE_TMP, if_data->ops);
67506 + if_data->ops = NULL;
67509 +static int
67510 +vlan_name_check(const char *input, char *ifname, int *vlan)
67512 + char iff_str[IFNAMSIZ];
67513 + char *vlan_str;
67514 + char *iff;
67516 + strncpy(iff_str, input, IFNAMSIZ);
67518 + iff = strtok(iff_str, ".");
67519 + vlan_str = strtok(NULL, ".");
67520 + *vlan = atoi(vlan_str);
67522 + if (!(iff && vlan_str && (vlan > 0)))
67523 + return 0;
67525 + strncpy(ifname, iff, IFNAMSIZ);
67526 + return 1;
67529 +static struct interface_ops*
67530 +vlan_create_ops(int vlan)
67532 + struct interface_ops *ops = XMALLOC (MTYPE_TMP, sizeof(struct interface_ops));
67533 + if (!ops)
67534 + return NULL;
67536 + memset (ops, 0, sizeof(struct interface_ops));
67537 + ops->type = INTERFACE_TYPE_VLAN;
67538 + ops->config = &vlan_config;
67539 + ops->show = &vlan_show;
67540 + ops->free = &vlan_free;
67541 + ops->info = (void*)vlan;
67542 + return ops;
67545 +static int
67546 +do_vlan (int cmd, char *name, int vlan)
67548 + struct vlan_ioctl_args args;
67550 + strncpy(args.device1, name, IFNAMSIZ);
67551 + args.cmd = cmd;
67552 + if (cmd == ADD_VLAN_CMD)
67553 + args.u.VID = vlan;
67555 + return if_ioctl(SIOCSIFVLAN, (caddr_t)&args);
67558 +DEFUN (create_vlan,
67559 + create_vlan_cmd,
67560 + "create vlan IFNAME",
67561 + "Create virtual interface\n"
67562 + "Create VLAN interface\n"
67563 + "VLAN interface name\n")
67565 + struct zebra_if *if_data;
67566 + struct interface *ifp;
67567 + char iff[IFNAMSIZ];
67568 + int vlan;
67570 + if (!vlan_name_check(argv[0], iff, &vlan))
67572 + vty_out (vty, "%% Invalid VLAN name%s", VTY_NEWLINE);
67573 + return CMD_WARNING;
67576 + ifp = if_lookup_by_name(argv[0]);
67577 + if (!ifp)
67579 + ifp = if_create (argv[0], strlen (argv[0]));
67580 + if (!ifp)
67582 + vty_out (vty, "%% Unable to create VLAN%s", VTY_NEWLINE);
67583 + return CMD_WARNING;
67587 + if_data = ifp->info;
67588 + if (if_data->ops)
67590 + vty_out (vty, "%% Interface is already owned by a protocol other then 802.1q%s", VTY_NEWLINE);
67591 + return CMD_WARNING;
67594 + if_data->ops = vlan_create_ops(vlan);
67595 + if (!if_data->ops)
67597 + vty_out (vty, "%% Unable to create VLAN%s", VTY_NEWLINE);
67598 + return CMD_WARNING;
67601 + if (do_vlan (ADD_VLAN_CMD, iff, vlan) < 0)
67603 + if_zebra_delete_ops (ifp);
67604 + vty_out (vty, "%% Unable creating VLAN%s", VTY_NEWLINE);
67605 + return CMD_WARNING;
67608 + return CMD_SUCCESS;
67611 +DEFUN (no_create_vlan,
67612 + no_create_vlan_cmd,
67613 + "no create vlan IFNAME",
67614 + NO_STR
67615 + "Delete virtual interface\n"
67616 + "Delete VLAN interface\n"
67617 + "VLAN interface name\n")
67619 + struct zebra_if *if_data;
67620 + struct interface *ifp;
67621 + char iff[IFNAMSIZ];
67622 + int vlan;
67624 + if (!vlan_name_check(argv[0], iff, &vlan))
67626 + vty_out (vty, "%% Invalid VLAN name%s", VTY_NEWLINE);
67627 + return CMD_WARNING;
67630 + ifp = if_lookup_by_name (argv[0]);
67631 + if (!ifp)
67632 + return CMD_WARNING;
67634 + if_data = ifp->info;
67635 + if (if_data && if_data->ops && if_data->ops->type == INTERFACE_TYPE_VLAN)
67637 + if_zebra_delete_ops (ifp);
67638 + do_vlan (DEL_VLAN_CMD, ifp->name, 0);
67641 + return CMD_SUCCESS;
67644 +void
67645 +if_vlan_init ()
67647 + install_element (CONFIG_NODE, &create_vlan_cmd);
67648 + install_element (CONFIG_NODE, &no_create_vlan_cmd);
67650 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/interface.c quagga-mpls/zebra/interface.c
67651 --- quagga/zebra/interface.c 2007-05-09 15:59:34.000000000 -0500
67652 +++ quagga-mpls/zebra/interface.c 2008-02-19 22:55:39.000000000 -0600
67653 @@ -88,6 +88,28 @@
67654 return 0;
67657 +void
67658 +if_zebra_delete_ops (struct interface *ifp)
67660 + struct zebra_if *zebra_if = ifp->info;
67662 + if (!zebra_if)
67663 + return;
67665 + if (zebra_if->ops)
67667 + if (zebra_if->ops->free)
67669 + zebra_if->ops->free(ifp);
67671 + else
67673 + XFREE (MTYPE_TMP, zebra_if->ops);
67674 + zebra_if->ops = NULL;
67679 /* Called when interface is deleted. */
67680 static int
67681 if_zebra_delete_hook (struct interface *ifp)
67682 @@ -98,6 +120,20 @@
67684 zebra_if = ifp->info;
67686 + /* Free interface specific ops block. */
67687 + if (zebra_if->ops)
67689 + if (zebra_if->ops->free)
67691 + zebra_if->ops->free(ifp);
67693 + else
67695 + XFREE (MTYPE_TMP, zebra_if->ops);
67696 + zebra_if->ops = NULL;
67700 /* Free installed address chains tree. */
67701 if (zebra_if->ipv4_subnets)
67702 route_table_finish (zebra_if->ipv4_subnets);
67703 @@ -673,6 +709,10 @@
67704 if (ifp->desc)
67705 vty_out (vty, " Description: %s%s", ifp->desc,
67706 VTY_NEWLINE);
67708 + if (zebra_if->ops && zebra_if->ops->show)
67709 + zebra_if->ops->show (vty, ifp);
67711 if (ifp->ifindex == IFINDEX_INTERNAL)
67713 vty_out(vty, " pseudo interface%s", VTY_NEWLINE);
67714 @@ -727,6 +767,14 @@
67715 vty_out(vty, "%s", VTY_NEWLINE);
67718 +#ifdef HAVE_MPLS
67719 + /* MPLS labelspace */
67720 + if (ifp->mpls_labelspace != -1)
67722 + vty_out(vty, " MPLS labelspace %u", ifp->mpls_labelspace);
67723 + vty_out(vty, "%s", VTY_NEWLINE);
67725 +#endif
67726 for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn))
67728 if (! rn->info)
67729 @@ -1519,6 +1567,18 @@
67730 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
67732 struct zebra_if *if_data;
67734 + if_data = ifp->info;
67736 + if (if_data->ops && if_data->ops->config)
67737 + if_data->ops->config (vty, ifp);
67739 + vty_out (vty, "!%s", VTY_NEWLINE);
67742 + for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
67744 + struct zebra_if *if_data;
67745 struct listnode *addrnode;
67746 struct connected *ifc;
67747 struct prefix *p;
67748 @@ -1536,7 +1596,10 @@
67749 while processing config script */
67750 if (ifp->bandwidth != 0)
67751 vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);
67753 +#ifdef HAVE_MPLS
67754 + if (ifp->mpls_labelspace != -1)
67755 + vty_out(vty, " mpls labelspace %u%s",ifp->mpls_labelspace,VTY_NEWLINE);
67756 +#endif
67757 if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
67758 vty_out(vty, " link-detect%s", VTY_NEWLINE);
67760 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/interface.h quagga-mpls/zebra/interface.h
67761 --- quagga/zebra/interface.h 2006-08-06 10:48:39.000000000 -0500
67762 +++ quagga-mpls/zebra/interface.h 2006-11-29 23:13:44.000000000 -0600
67763 @@ -27,6 +27,7 @@
67764 #ifdef HAVE_IRDP
67765 #include "zebra/irdp.h"
67766 #endif
67767 +#include "vty.h"
67769 /* For interface multicast configuration. */
67770 #define IF_ZEBRA_MULTICAST_UNSPEC 0
67771 @@ -175,6 +176,26 @@
67773 #endif /* RTADV */
67775 +enum interface_type
67777 + INTERFACE_TYPE_VLAN = 1,
67778 + INTERFACE_TYPE_TUNNEL,
67779 + INTERFACE_TYPE_MAX
67782 +struct interface_ops
67784 + enum interface_type type;
67785 + void (*config)(struct vty*, struct interface*);
67786 + void (*show)(struct vty*, struct interface*);
67787 + int (*create)(struct interface*);
67788 + int (*delete)(struct interface*);
67789 + int (*create_check)(struct interface*);
67790 + int (*delete_check)(struct interface*);
67791 + void (*free)(struct interface*);
67792 + void *info;
67795 /* `zebra' daemon local interface structure. */
67796 struct zebra_if
67798 @@ -193,6 +214,9 @@
67799 /* Installed addresses chains tree. */
67800 struct route_table *ipv4_subnets;
67802 + /* Interface specific operations. */
67803 + struct interface_ops *ops;
67805 #ifdef RTADV
67806 struct rtadvconf rtadv;
67807 #endif /* RTADV */
67808 @@ -217,6 +241,7 @@
67809 extern void if_down (struct interface *);
67810 extern void if_refresh (struct interface *);
67811 extern void if_flags_update (struct interface *, uint64_t);
67812 +extern void if_zebra_delete_ops (struct interface *);
67813 extern int if_subnet_add (struct interface *, struct connected *);
67814 extern int if_subnet_delete (struct interface *, struct connected *);
67816 @@ -238,4 +263,7 @@
67817 extern int if_kvm_get_mtu (struct interface *);
67818 #endif /* BSDI */
67820 +extern void if_vlan_init();
67821 +extern void if_tunnel_init();
67823 #endif /* _ZEBRA_INTERFACE_H */
67824 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/ioctl.c quagga-mpls/zebra/ioctl.c
67825 --- quagga/zebra/ioctl.c 2008-09-04 20:37:37.000000000 -0500
67826 +++ quagga-mpls/zebra/ioctl.c 2008-09-07 20:23:36.000000000 -0500
67827 @@ -52,7 +52,7 @@
67829 int sock;
67830 int ret;
67831 - int err;
67832 + int err = 0;
67834 if (zserv_privs.change(ZPRIVS_RAISE))
67835 zlog (NULL, LOG_ERR, "Can't raise privileges");
67836 @@ -85,7 +85,7 @@
67838 int sock;
67839 int ret;
67840 - int err;
67841 + int err = 0;
67843 if (zserv_privs.change(ZPRIVS_RAISE))
67844 zlog (NULL, LOG_ERR, "Can't raise privileges");
67845 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/kernel_socket.c quagga-mpls/zebra/kernel_socket.c
67846 --- quagga/zebra/kernel_socket.c 2008-09-04 20:37:37.000000000 -0500
67847 +++ quagga-mpls/zebra/kernel_socket.c 2008-09-07 20:23:36.000000000 -0500
67848 @@ -761,11 +761,13 @@
67849 rtm_read (struct rt_msghdr *rtm)
67851 int flags;
67852 - u_char zebra_flags;
67853 + u_short zebra_flags;
67854 union sockunion dest, mask, gate;
67855 char ifname[INTERFACE_NAMSIZ + 1];
67856 short ifnlen = 0;
67857 + struct zapi_nexthop nh;
67859 + memset(&nh, 0, sizeof(struct zapi_nexthop));
67860 zebra_flags = 0;
67862 /* Read destination and netmask and gateway from rtm message
67863 @@ -802,13 +804,20 @@
67865 /* This is a reject or blackhole route */
67866 if (flags & RTF_REJECT)
67867 - SET_FLAG (zebra_flags, ZEBRA_FLAG_REJECT);
67868 - if (flags & RTF_BLACKHOLE)
67869 - SET_FLAG (zebra_flags, ZEBRA_FLAG_BLACKHOLE);
67871 + SET_FLAG (nh.type, ZEBRA_NEXTHOP_DROP);
67872 + nh.gw.drop = ZEBRA_DROP_REJECT;
67874 + else if (flags & RTF_BLACKHOLE)
67876 + SET_FLAG (nh.type, ZEBRA_NEXTHOP_DROP);
67877 + nh.gw.drop = ZEBRA_DROP_BLACKHOLE;
67880 if (dest.sa.sa_family == AF_INET)
67882 struct prefix_ipv4 p;
67883 + struct zapi_nexthop znh;
67885 p.family = AF_INET;
67886 p.prefix = dest.sin.sin_addr;
67887 @@ -816,6 +825,10 @@
67888 p.prefixlen = IPV4_MAX_PREFIXLEN;
67889 else
67890 p.prefixlen = ip_masklen (mask.sin.sin_addr);
67892 + memset (&znh, 0, sizeof (struct zapi_nexthop));
67893 + znh.type = ZEBRA_NEXTHOP_IPV4;
67894 + znh.gw.ipv4 = gate.sin;
67896 /* Catch self originated messages and match them against our current RIB.
67897 * At the same time, ignore unconfirmed messages, they should be tracked
67898 @@ -827,7 +840,7 @@
67899 int ret;
67900 if (! IS_ZEBRA_DEBUG_RIB)
67901 return;
67902 - ret = rib_lookup_ipv4_route (&p, &gate);
67903 + ret = rib_lookup_route_nexthop ((struct prefix*)&p, &znh);
67904 inet_ntop (AF_INET, &p.prefix, buf, INET_ADDRSTRLEN);
67905 switch (rtm->rtm_type)
67907 @@ -891,17 +904,20 @@
67908 * to specify the route really
67910 if (rtm->rtm_type == RTM_CHANGE)
67911 - rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,
67912 - NULL, 0, 0);
67913 + rib_delete_route (ZEBRA_ROUTE_KERNEL, zebra_flags,
67914 + (struct prefix*)&p, &nh, 0);
67916 + nh.gw.ipv4 = gate.sin.sin_addr;
67917 + SET_FLAG (nh.type, ZEBRA_NEXTHOP_IPV4);
67919 if (rtm->rtm_type == RTM_GET
67920 || rtm->rtm_type == RTM_ADD
67921 || rtm->rtm_type == RTM_CHANGE)
67922 - rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags,
67923 - &p, &gate.sin.sin_addr, NULL, 0, 0, 0, 0);
67924 + rib_add_route (ZEBRA_ROUTE_KERNEL, zebra_flags, (struct prefix*)&p,
67925 + &nh, NULL, 0, 0, 0);
67926 else
67927 - rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags,
67928 - &p, &gate.sin.sin_addr, 0, 0);
67929 + rib_delete_route (ZEBRA_ROUTE_KERNEL, zebra_flags,
67930 + (struct prefix*)&p, &nh, 0);
67932 #ifdef HAVE_IPV6
67933 if (dest.sa.sa_family == AF_INET6)
67934 @@ -933,17 +949,26 @@
67935 * to specify the route really
67937 if (rtm->rtm_type == RTM_CHANGE)
67938 - rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,
67939 + rib_delete_route (ZEBRA_ROUTE_KERNEL, zebra_flags, (struct prefix*)&p,
67940 NULL, 0, 0);
67942 + nh.gw.ipv6 = gate.sin6.sin_addr6;
67943 + SET_FLAG (nh.type, ZEBRA_NEXTHOP_IPV6);
67945 + if (ifindex)
67947 + nh.intf.index = ifindex;
67948 + SET_FLAG (nh.type, ZEBRA_NEXTHOP_IFINDEX);
67951 if (rtm->rtm_type == RTM_GET
67952 || rtm->rtm_type == RTM_ADD
67953 || rtm->rtm_type == RTM_CHANGE)
67954 - rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags,
67955 - &p, &gate.sin6.sin6_addr, ifindex, 0, 0, 0);
67956 + rib_add_route (ZEBRA_ROUTE_KERNEL, zebra_flags, (struct prefix*)&p,
67957 + &nh, 0, 0, 0);
67958 else
67959 - rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags,
67960 - &p, &gate.sin6.sin6_addr, ifindex, 0);
67961 + rib_delete_route (ZEBRA_ROUTE_KERNEL, zebra_flags,
67962 + (struct prefix*)&p, &nh, 0);
67964 #endif /* HAVE_IPV6 */
67966 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/main.c quagga-mpls/zebra/main.c
67967 --- quagga/zebra/main.c 2008-09-04 20:37:37.000000000 -0500
67968 +++ quagga-mpls/zebra/main.c 2008-09-07 20:23:36.000000000 -0500
67969 @@ -39,6 +39,7 @@
67970 #include "zebra/router-id.h"
67971 #include "zebra/irdp.h"
67972 #include "zebra/rtadv.h"
67973 +#include "zebra/interface.h"
67975 /* Zebra instance */
67976 struct zebra_t zebrad =
67977 @@ -169,6 +170,9 @@
67979 if (!retain_mode)
67980 rib_close ();
67981 +#ifdef HAVE_MPLS
67982 + mpls_close ();
67983 +#endif
67984 #ifdef HAVE_IRDP
67985 irdp_finish();
67986 #endif
67987 @@ -320,16 +324,24 @@
67988 /* Zebra related initialize. */
67989 zebra_init ();
67990 rib_init ();
67991 +#ifdef HAVE_MPLS
67992 + mpls_init ();
67993 +#endif
67994 zebra_if_init ();
67995 zebra_debug_init ();
67996 router_id_init();
67997 zebra_vty_init ();
67998 +#ifdef HAVE_MPLS
67999 + mpls_vty_init ();
68000 +#endif
68001 access_list_init ();
68002 prefix_list_init ();
68003 rtadv_init ();
68004 #ifdef HAVE_IRDP
68005 irdp_init();
68006 #endif
68007 + if_vlan_init();
68008 + if_tunnel_init();
68010 /* For debug purpose. */
68011 /* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */
68012 @@ -338,6 +350,10 @@
68013 kernel_init ();
68014 interface_list ();
68015 route_read ();
68016 +#ifdef HAVE_MPLS
68017 + mpls_kernel_init ();
68018 + mpls_read ();
68019 +#endif
68021 /* Sort VTY commands. */
68022 sort_node ();
68023 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/Makefile.am quagga-mpls/zebra/Makefile.am
68024 --- quagga/zebra/Makefile.am 2007-05-02 10:28:33.000000000 -0500
68025 +++ quagga-mpls/zebra/Makefile.am 2008-02-22 00:14:20.000000000 -0600
68026 @@ -15,39 +15,50 @@
68027 kernel_method = @KERNEL_METHOD@
68028 other_method = @OTHER_METHOD@
68029 ioctl_method = @IOCTL_METHOD@
68030 +mpls_method = @MPLS_METHOD@
68032 otherobj = $(ioctl_method) $(ipforward) $(if_method) $(if_proc) \
68033 - $(rt_method) $(rtread_method) $(kernel_method) $(other_method)
68034 + $(rt_method) $(rtread_method) $(kernel_method) $(other_method) \
68035 + $(mpls_method)
68037 sbin_PROGRAMS = zebra
68039 -noinst_PROGRAMS = testzebra
68040 +#noinst_PROGRAMS = testzebra
68042 +mpls_sources=
68043 +mpls_headers=
68044 +if MPLS_ENABLED
68045 +mpls_sources+=mpls_vty.c mpls_lib.c
68046 +mpls_headers+=mpls_vty.h mpls_lib.h
68047 +endif
68049 zebra_SOURCES = \
68050 zserv.c main.c interface.c connected.c zebra_rib.c zebra_routemap.c \
68051 redistribute.c debug.c rtadv.c zebra_snmp.c zebra_vty.c \
68052 - irdp_main.c irdp_interface.c irdp_packet.c router-id.c
68053 + irdp_main.c irdp_interface.c irdp_packet.c router-id.c if_vlan.c \
68054 + if_tunnel.c $(mpls_sources)
68056 -testzebra_SOURCES = test_main.c zebra_rib.c interface.c connected.c debug.c \
68057 - zebra_vty.c \
68058 - kernel_null.c redistribute_null.c ioctl_null.c misc_null.c
68059 +#testzebra_SOURCES = test_main.c zebra_rib.c interface.c connected.c debug.c \
68060 +# zebra_vty.c \
68061 +# kernel_null.c redistribute_null.c ioctl_null.c misc_null.c
68063 noinst_HEADERS = \
68064 connected.h ioctl.h rib.h rt.h zserv.h redistribute.h debug.h rtadv.h \
68065 - interface.h ipforward.h irdp.h router-id.h kernel_socket.h
68066 + interface.h ipforward.h irdp.h router-id.h kernel_socket.h netlink.h \
68067 + $(mpls_headers)
68069 zebra_LDADD = $(otherobj) $(LIBCAP) $(LIB_IPV6) ../lib/libzebra.la
68071 -testzebra_LDADD = $(LIBCAP) $(LIB_IPV6) ../lib/libzebra.la
68072 +#testzebra_LDADD = $(LIBCAP) $(LIB_IPV6) ../lib/libzebra.la
68074 zebra_DEPENDENCIES = $(otherobj)
68076 EXTRA_DIST = if_ioctl.c if_ioctl_solaris.c if_netlink.c if_proc.c \
68077 if_sysctl.c ipforward_aix.c ipforward_ews.c ipforward_proc.c \
68078 - ipforward_solaris.c ipforward_sysctl.c rt_ioctl.c rt_netlink.c \
68079 + ipforward_solaris.c ipforward_sysctl.c rt_ioctl.c netlink.c \
68080 rt_socket.c rtread_netlink.c rtread_proc.c rtread_sysctl.c \
68081 rtread_getmsg.c kernel_socket.c kernel_netlink.c mtu_kvm.c \
68082 - ioctl.c ioctl_solaris.c \
68083 + ioctl.c ioctl_solaris.c netlink.c\
68084 GNOME-SMI GNOME-PRODUCT-ZEBRA-MIB
68086 #client : client_main.o ../lib/libzebra.la
68087 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/mpls_ioctl.c quagga-mpls/zebra/mpls_ioctl.c
68088 --- quagga/zebra/mpls_ioctl.c 1969-12-31 18:00:00.000000000 -0600
68089 +++ quagga-mpls/zebra/mpls_ioctl.c 2006-12-06 20:53:36.000000000 -0600
68090 @@ -0,0 +1,205 @@
68091 +#include "zebra.h"
68092 +#include "mpls_lib.h"
68094 +static int mpls_linux_fd = 0;
68096 +int
68097 +mpls_ctrl_show_hardware(struct *vty)
68099 + vty_out(vty, "MPLS-Linux: %d.%d%d%d%s ioctl control%s",
68100 + (MPLS_LINUX_VERSION >> 24) & 0xFF,
68101 + (MPLS_LINUX_VERSION >> 16) & 0xFF,
68102 + (MPLS_LINUX_VERSION >> 8) & 0xFF,
68103 + (MPLS_LINUX_VERSION) & 0xFF, VTY_NEWLINE);
68104 + return CMD_SUCCESS;
68107 +int
68108 +mpls_kernel_init()
68110 + mpls_linux_fd = socket(AF_INET,SOCK_DGRAM,0);
68111 +#if 0
68112 + struct ifreq ifr;
68113 +#endif
68115 + if(mpls_linux_fd < 0)
68117 + return -1;
68120 +#if 0
68121 + ioctl(mpls_linux_fd,SIOCMPLSILMFLUSH,&ifr);
68122 + ioctl(mpls_linux_fd,SIOCMPLSNHLFEFLUSH,&ifr);
68123 +#endif
68125 + return 0;
68128 +int
68129 +mpls_ctrl_nhlfe_unregister(struct zmpls_out_segment *old)
68131 + struct mpls_out_label_req mol_req;
68133 + mol_req.mol_label.ml_type = MPLS_LABEL_KEY;
68134 + mol_req.mol_label.u.ml_key = old->out_key;
68135 + return ioctl(mpls_linux_fd,SIOCMPLSNHLFEDEL,&mol_req);
68138 +int
68139 +mpls_ctrl_nhlfe_register(struct zmpls_out_segment *new)
68141 + struct mpls_out_label_req mol_req;
68142 + struct mpls_instr_req mir_req;
68143 + struct interface *ifp;
68144 + int result;
68146 + mol_req.mol_label.ml_type = MPLS_LABEL_KEY;
68147 + mol_req.mol_label.u.ml_key = 0;
68149 + result = ioctl(mpls_linux_fd,SIOCMPLSNHLFEADD,&mol_req);
68150 + if (result < 0)
68152 + return -1;
68154 + new->out_key = mol_req.mol_label.u.ml_key;
68156 + mir_req.mir_direction = MPLS_OUT;
68157 + memcpy(&mir_req.mir_label,&mol_req.mol_label,sizeof(struct mpls_label));
68159 + mir_req.mir_instr[0].mir_opcode = MPLS_OP_PUSH;
68160 + mir_req.mir_instr[0].mir_data.push.ml_type = MPLS_LABEL_GEN;
68161 + mir_req.mir_instr[0].mir_data.push.u.ml_gen = new->push.u.gen;
68163 + mir_req.mir_instr[1].mir_opcode = MPLS_OP_SET;
68165 + if (new->nh.type & NEXTHOP_TYPE_IFNAME)
68167 + ifp = if_lookup_by_name (new->nh.ifname);
68168 + mir_req.mir_instr[1].mir_data.set.mni_if = ifp ? ifp->ifindex : 0;
68171 + if (new->nh.type & NEXTHOP_TYPE_IPV4)
68173 + struct sockaddr_in addr;
68174 + addr.sin_family = AF_INET;
68175 + addr.sin_addr = new->nh.gate.ipv4;
68176 + memcpy(&mir_req.mir_instr[1].mir_data.set.mni_addr, &addr, sizeof(addr));
68178 + else if (new->nh.type & NEXTHOP_TYPE_IPV6)
68180 + struct sockaddr_in6 addr;
68181 + addr.sin6_family = AF_INET6;
68182 + addr.sin6_addr = new->nh.gate.ipv6;
68183 + memcpy(&mir_req.mir_instr[1].mir_data.set.mni_addr, &addr, sizeof(addr));
68185 + else
68187 + assert (0);
68190 + mir_req.mir_instr_length = 2;
68192 + result = ioctl(mpls_linux_fd,SIOCSMPLSOUTINSTR,&mir_req);
68194 + return (result < 0) ? mpls_ctrl_nhlfe_unregister(new) : 0;
68197 +int
68198 +mpls_ctrl_ilm_unregister(struct zmpls_in_segment *old)
68200 + struct mpls_in_label_req mil_req;
68202 + mil_req.mil_label.ml_type = MPLS_LABEL_GEN;
68203 + mil_req.mil_label.u.ml_gen = old->label.u.gen;
68204 + mil_req.mil_label.ml_index = old->labelspace;
68206 + return ioctl(mpls_linux_fd,SIOCMPLSILMDEL,&mil_req);
68209 +int
68210 +mpls_ctrl_ilm_register(struct zmpls_in_segment *new)
68212 + struct mpls_in_label_req mil_req;
68213 + int result;
68215 + mil_req.mil_label.ml_type = MPLS_LABEL_GEN;
68216 + mil_req.mil_label.u.ml_gen = new->label.u.gen;
68217 + mil_req.mil_label.ml_index = new->labelspace;
68219 + result = ioctl(mpls_linux_fd,SIOCMPLSILMADD,&mil_req);
68221 + if (result < 0)
68223 + return -1;
68226 + return 0;
68229 +int mpls_ctrl_xc_register(struct zmpls_in_segment *in,
68230 + struct zmpls_out_segment *out)
68232 + struct mpls_xconnect_req mx_req;
68233 + int result;
68235 + mx_req.mx_in.ml_type = MPLS_LABEL_GEN;
68236 + mx_req.mx_in.u.ml_gen = in->label.u.gen;
68237 + mx_req.mx_in.ml_index = in->labelspace;
68238 + mx_req.mx_out.ml_type = MPLS_LABEL_KEY;
68239 + mx_req.mx_out.u.ml_key = out->out_key;
68241 + result = ioctl(mpls_linux_fd,SIOCMPLSXCADD,&mx_req);
68242 + if (result < 0)
68244 + return -1;
68247 + return 0;
68250 +int mpls_ctrl_xc_unregister(struct zmpls_in_segment *in,
68251 + struct zmpls_out_segment *out)
68253 + struct mpls_xconnect_req mx_req;
68254 + int result;
68256 + mx_req.mx_in.ml_type = MPLS_LABEL_GEN;
68257 + mx_req.mx_in.u.ml_gen = in->label.u.gen;
68258 + mx_req.mx_in.ml_index = in->labelspace;
68259 + mx_req.mx_out.ml_type = MPLS_LABEL_KEY;
68260 + mx_req.mx_out.u.ml_key = out->out_key;
68262 + result = ioctl(mpls_linux_fd,SIOCMPLSXCDEL,&mx_req);
68263 + if (result < 0)
68265 + return -1;
68268 + return 0;
68271 +int mpls_ctrl_ftn_register(struct zmpls_ftn *ftn)
68273 + return 0;
68276 +int mpls_ctrl_ftn_unregister(struct zmpls_ftn *ftn)
68278 + return 0;
68281 +int mpls_ctrl_set_interface_labelspace(struct interface *ifp)
68283 + struct mpls_labelspace_req mls_req;
68285 + mls_req.mls_ifindex = ifp->ifindex;
68286 + mls_req.mls_labelspace = ifp->mpls_labelspace;
68287 + ioctl(mpls_linux_fd,SIOCSLABELSPACEMPLS,&mls_req);
68289 + return 0;
68292 +int
68293 +mpls_read (void)
68296 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/mpls_lib.c quagga-mpls/zebra/mpls_lib.c
68297 --- quagga/zebra/mpls_lib.c 1969-12-31 18:00:00.000000000 -0600
68298 +++ quagga-mpls/zebra/mpls_lib.c 2008-02-22 22:30:07.000000000 -0600
68299 @@ -0,0 +1,768 @@
68301 + * MPLS Label Information Base for zebra daemon.
68303 + * Copyright (C) 2004 James R. Leu
68305 + * This file is part of Quagga routing suite.
68307 + * Quagga is free software; you can redistribute it and/or modify it
68308 + * under the terms of the GNU General Public License as published by the
68309 + * Free Software Foundation; either version 2, or (at your option) any
68310 + * later version.
68312 + * Quagga is distributed in the hope that it will be useful, but
68313 + * WITHOUT ANY WARRANTY; without even the implied warranty of
68314 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
68315 + * General Public License for more details.
68317 + * You should have received a copy of the GNU General Public License
68318 + * along with GNU Zebra; see the file COPYING. If not, write to the Free
68319 + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
68320 + * 02111-1307, USA.
68321 + */
68323 +#include <zebra.h>
68325 +#ifdef HAVE_MPLS
68327 +#include "linklist.h"
68328 +#include "memory.h"
68329 +#include "if.h"
68330 +#include "log.h"
68331 +#include "mpls_lib.h"
68332 +#include "redistribute.h"
68333 +#include "zclient.h"
68335 +extern struct zebra_t zebrad;
68336 +extern void rib_queue_add (struct zebra_t *zebra, struct route_node *rn);
68337 +void mpls_xc_unregister(struct zmpls_xc *old);
68339 +/*************************** out segment *****************************/
68341 +int
68342 +mpls_nexthop_ready(struct zapi_nexthop *nh)
68344 + struct interface *ifp = NULL;
68345 + int match = 0;
68346 + int try = 0;
68348 + if (CHECK_FLAG (nh->type, ZEBRA_NEXTHOP_IFINDEX))
68350 + ifp = if_lookup_by_index(nh->intf.index);
68351 + try++;
68352 + if (ifp && if_is_operative(ifp))
68353 + match++;
68355 + else if (CHECK_FLAG (nh->type, ZEBRA_NEXTHOP_IFNAME))
68357 + ifp = if_lookup_by_name(nh->intf.name);
68358 + try++;
68359 + if (ifp && if_is_operative(ifp))
68360 + match++;
68363 + if (CHECK_FLAG (nh->type, ZEBRA_NEXTHOP_IPV6))
68366 + try++;
68367 + if (ifp)
68369 + struct listnode *node;
68370 + struct connected *ifc;
68371 + struct prefix np;
68372 + memset (&np, 0, sizeof (struct prefix));
68374 + np.family = AF_INET6;
68375 + np.prefixlen = IPV6_MAX_PREFIXLEN;
68376 + np.u.prefix6 = nh->gw.ipv6;
68378 + for (ALL_LIST_ELEMENTS_RO(ifp->connected,node,ifc))
68380 + if (prefix_match(ifc->address, &np))
68382 + match++;
68383 + break;
68388 + else if (CHECK_FLAG (nh->type, ZEBRA_NEXTHOP_IPV4))
68390 + try++;
68391 + if (!ifp)
68393 + ifp = if_lookup_address(nh->gw.ipv4);
68394 + if (ifp && if_is_operative(ifp))
68395 + match++;
68397 + else
68399 + struct listnode *node;
68400 + struct connected *ifc;
68401 + struct prefix np;
68402 + memset (&np, 0, sizeof (struct prefix));
68404 + np.family = AF_INET;
68405 + np.prefixlen = IPV4_MAX_PREFIXLEN;
68406 + np.u.prefix4 = nh->gw.ipv4;
68408 + for (ALL_LIST_ELEMENTS_RO(ifp->connected,node,ifc))
68410 + if (prefix_match(ifc->address, &np))
68412 + match++;
68413 + break;
68419 + return (try && try == match) ? 1 : 0;
68422 +static
68423 +int mpls_out_segment_cmp(void *val1, void *val2)
68425 + struct zmpls_out_segment *v1 = val1;
68426 + struct zmpls_out_segment *v2 = val2;
68428 + if (v1->index > v2->index)
68430 + return 1;
68432 + else if (v1->index < v2->index)
68434 + return -1;
68436 + return 0;
68439 +static int mpls_out_segment_nextindex = 1;
68441 +struct list mpls_out_segment_list = {
68442 + .head = NULL,
68443 + .tail = NULL,
68444 + .count = 0,
68445 + .cmp = mpls_out_segment_cmp,
68446 + .del = NULL,
68449 +unsigned int
68450 +mpls_out_segment_find_index_by_nexthop(struct zapi_nexthop *nh)
68452 + struct listnode *node;
68453 + struct zmpls_out_segment *old;
68455 + for (ALL_LIST_ELEMENTS_RO(&mpls_out_segment_list,node,old))
68457 + if (zapi_nexthop_match(&old->nh, nh, ZEBRA_NEXTHOP_ALL))
68458 + goto found;
68460 + return 0;
68461 +found:
68462 + return old->index;
68465 +unsigned int
68466 +mpls_out_segment_find_index_by_nhlfe(struct zmpls_out_segment *out)
68468 + struct listnode *node;
68469 + struct zmpls_out_segment *old;
68471 + for (ALL_LIST_ELEMENTS_RO(&mpls_out_segment_list,node,old))
68473 + if (old->owner == out->owner &&
68474 + zapi_nexthop_match(&old->nh, &out->nh, ZEBRA_NEXTHOP_ALL))
68475 + goto found;
68477 + return 0;
68478 +found:
68479 + return old->index;
68482 +struct zmpls_out_segment*
68483 +mpls_out_segment_find(unsigned int index)
68485 + struct listnode *node;
68486 + struct zmpls_out_segment *old;
68488 + for (ALL_LIST_ELEMENTS_RO(&mpls_out_segment_list,node,old))
68489 + if (index == old->index)
68490 + goto found;
68492 + return NULL;
68493 +found:
68494 + return old;
68497 +struct zmpls_out_segment*
68498 +mpls_out_segment_find_by_out_key(unsigned int key)
68500 + struct listnode *node;
68501 + struct zmpls_out_segment *old;
68503 + for (ALL_LIST_ELEMENTS_RO(&mpls_out_segment_list,node,old))
68504 + if (key == old->out_key)
68505 + goto found;
68507 + return NULL;
68508 +found:
68509 + return old;
68512 +static int
68513 +do_mpls_out_segment_unregister(struct zmpls_out_segment *old)
68515 + int ret = 0;
68516 + if (old->owner != ZEBRA_ROUTE_KERNEL && old->installed)
68517 + ret = mpls_ctrl_nhlfe_unregister(old);
68519 + redistribute_delete_mpls_out_segment (old);
68520 + LISTNODE_DETACH(&mpls_out_segment_list, &old->global);
68521 + XFREE (MTYPE_TMP, old);
68522 + return ret;
68525 +int
68526 +mpls_out_segment_unregister(struct zmpls_out_segment *out)
68528 + struct zmpls_out_segment *old = mpls_out_segment_find (out->index);
68530 + if (!old)
68531 + return 1;
68533 + return do_mpls_out_segment_unregister (old);
68536 +int
68537 +mpls_out_segment_unregister_by_index(unsigned int index)
68539 + struct zmpls_out_segment *old = mpls_out_segment_find (index);
68541 + if (!old)
68542 + return 1;
68544 + return do_mpls_out_segment_unregister (old);
68547 +int
68548 +mpls_out_segment_register(struct zmpls_out_segment *out)
68550 + struct zmpls_out_segment *new;
68551 + int err;
68553 + if ((err = mpls_out_segment_find_index_by_nhlfe (out)))
68554 + return err;
68556 + new = XMALLOC (MTYPE_TMP, sizeof (struct zmpls_out_segment));
68557 + if (!new)
68558 + return -ENOMEM;
68560 + memcpy (new, out, sizeof (struct zmpls_out_segment));
68562 + new->global.data = new;
68563 + new->global.next = NULL;
68564 + new->global.prev = NULL;
68565 + out->index = new->index = mpls_out_segment_nextindex++;
68566 + new->installed = out->installed = 0;
68568 + if (new->owner != ZEBRA_ROUTE_KERNEL)
68570 + if (mpls_nexthop_ready(&new->nh))
68572 + if ((err = mpls_ctrl_nhlfe_register(new))) {
68573 + XFREE (MTYPE_TMP, new);
68574 + return err;
68576 + out->out_key = new->out_key;
68577 + new->installed = out->installed = 1;
68578 + } else {
68579 + /*
68580 + * in the future we should add this to a specific list, instead of
68581 + * relying on brute force search foreach interface/address event
68582 + */
68584 + } else {
68585 + new->installed = out->installed = 1;
68588 + LISTNODE_ATTACH(&mpls_out_segment_list, &new->global);
68590 + if (new->installed)
68591 + redistribute_add_mpls_out_segment (new);
68593 + return 0;
68596 +/*************************** in segment *****************************/
68598 +struct list mpls_in_segment_list = {
68599 + .head = NULL,
68600 + .tail = NULL,
68601 + .count = 0,
68602 + .cmp = NULL,
68603 + .del = NULL,
68606 +int
68607 +mpls_in_segment_match(struct zmpls_in_segment *a, struct zmpls_in_segment *b)
68610 + if (a->labelspace == b->labelspace)
68611 + return mpls_label_match(&a->label, &b->label);
68613 + return 0;
68616 +struct zmpls_in_segment*
68617 +mpls_in_segment_find(struct zmpls_in_segment *in)
68619 + struct listnode *node;
68620 + struct zmpls_in_segment *old;
68622 + for (ALL_LIST_ELEMENTS_RO(&mpls_in_segment_list,node,old))
68623 + if (mpls_in_segment_match(in, old))
68624 + return old;
68626 + return NULL;
68629 +static int
68630 +do_mpls_in_segment_unregister(struct zmpls_in_segment *in, int flag)
68632 + if (in->installed)
68633 + mpls_ctrl_ilm_unregister (in);
68635 + if (in->xc)
68637 + struct zmpls_xc *xc = mpls_xc_find(in->xc);
68638 + if (xc)
68639 + mpls_xc_unregister (xc);
68640 + else
68641 + zlog_warn("do_mpls_in_segment_unregister: xc %d does not exist", in->xc);
68643 + if (flag)
68644 + mpls_out_segment_unregister_by_index (xc->out_index);
68647 + redistribute_delete_mpls_in_segment (in);
68648 + LISTNODE_DETACH (&mpls_in_segment_list, &in->global);
68649 + XFREE (MTYPE_TMP, in);
68651 + return 0;
68654 +int
68655 +mpls_in_segment_unregister(struct zmpls_in_segment *in, int flag)
68657 + struct zmpls_in_segment *old = mpls_in_segment_find (in);
68659 + if (!old)
68660 + return 1;
68662 + return do_mpls_in_segment_unregister (old, flag);
68665 +int
68666 +mpls_in_segment_register(struct zmpls_in_segment *in, int install)
68668 + struct zmpls_in_segment *new;
68669 + int ret = 0;
68671 + if (mpls_in_segment_find (in))
68672 + return 1;
68674 + new = XMALLOC (MTYPE_TMP, sizeof (*new));
68675 + if (!new)
68676 + return 1;
68678 + memcpy (new, in, sizeof (*new));
68679 + new->global.data = new;
68680 + new->global.next = NULL;
68681 + new->global.prev = NULL;
68682 + new->xc = 0;
68684 + if (new->owner != ZEBRA_ROUTE_KERNEL && install)
68685 + ret = mpls_ctrl_ilm_register(new);
68687 + if (ret) {
68688 + XFREE (MTYPE_TMP, new);
68689 + return ret;
68692 + LISTNODE_ATTACH(&mpls_in_segment_list, &new->global);
68693 + redistribute_add_mpls_in_segment (new);
68694 + return 0;
68697 +/******************************* cross connect ******************************/
68699 +static int mpls_xc_cmp(void *val1, void *val2)
68701 + struct zmpls_xc *v1 = val1;
68702 + struct zmpls_xc *v2 = val2;
68704 + if (v1->index > v2->index)
68705 + return 1;
68706 + else if (v1->index < v2->index)
68707 + return -1;
68708 + return 0;
68711 +static int mpls_xc_nextindex = 1;
68713 +struct list mpls_xc_list = {
68714 + .head = NULL,
68715 + .tail = NULL,
68716 + .count = 0,
68717 + .cmp = mpls_xc_cmp,
68718 + .del = NULL,
68721 +struct zmpls_xc *mpls_xc_find(unsigned int index)
68723 + struct listnode *node;
68724 + struct zmpls_xc *xc;
68726 + for (ALL_LIST_ELEMENTS_RO(&mpls_xc_list,node,xc))
68727 + if (index == xc->index)
68728 + return xc;
68730 + return NULL;
68733 +int
68734 +mpls_xc_register(struct zmpls_xc *xc)
68736 + struct zmpls_in_segment tmp;
68737 + struct zmpls_out_segment *out;
68738 + struct zmpls_in_segment *in;
68739 + struct zmpls_xc *new;
68741 + tmp.labelspace = xc->in_labelspace;
68742 + memcpy(&tmp.label, &xc->in_label, sizeof(struct zmpls_label));
68743 + in = mpls_in_segment_find (&tmp);
68744 + out = mpls_out_segment_find (xc->out_index);
68746 + if (in->xc)
68747 + return 1;
68749 + new = XMALLOC (MTYPE_TMP, sizeof (*new));
68750 + if (!new)
68751 + return 1;
68753 + new->global.data = new;
68754 + new->global.next = NULL;
68755 + new->global.prev = NULL;
68757 + new->in_labelspace = in->labelspace;
68758 + memcpy(&new->in_label, &in->label, sizeof(struct zmpls_label));
68759 + new->out_index = out->index;
68760 + new->index = mpls_xc_nextindex++;
68761 + in->xc = new->index;
68763 + LISTNODE_ATTACH(&mpls_xc_list, &new->global);
68765 + if (in->owner != ZEBRA_ROUTE_KERNEL)
68767 + if (in->installed && out->installed)
68769 + mpls_ctrl_xc_register(in, out);
68770 + new->installed = xc->installed = 1;
68771 + } else {
68772 + new->installed = xc->installed = 0;
68774 + } else {
68775 + new->installed = xc->installed = 1;
68778 + if (new->installed)
68779 + redistribute_add_mpls_xc (new);
68781 + return 0;
68784 +void
68785 +mpls_xc_unregister(struct zmpls_xc *old)
68787 + struct zmpls_out_segment *out;
68788 + struct zmpls_in_segment *in;
68789 + struct zmpls_in_segment tmp;
68791 + tmp.labelspace = old->in_labelspace;
68792 + memcpy(&tmp.label, &old->in_label, sizeof(struct zmpls_label));
68793 + in = mpls_in_segment_find(&tmp);
68794 + out = mpls_out_segment_find(old->out_index);
68796 + if (old->installed)
68797 + mpls_ctrl_xc_unregister(in, out);
68799 + in->xc = 0;
68801 + redistribute_delete_mpls_xc(old);
68802 + LISTNODE_DETACH(&mpls_xc_list, &old->global);
68803 + XFREE (MTYPE_TMP, old);
68806 +/*********************************** FTN **********************************/
68808 +static int mpls_ftn_cmp(void *val1, void *val2)
68810 + struct zmpls_xc *v1 = val1;
68811 + struct zmpls_xc *v2 = val2;
68813 + if (v1->index > v2->index)
68814 + return 1;
68815 + else if (v1->index < v2->index)
68816 + return -1;
68817 + return 0;
68820 +static int mpls_ftn_nextindex = 1;
68822 +struct list mpls_ftn_list = {
68823 + .head = NULL,
68824 + .tail = NULL,
68825 + .count = 0,
68826 + .cmp = mpls_ftn_cmp,
68827 + .del = NULL,
68830 +struct zmpls_ftn*
68831 +mpls_ftn_find(unsigned int index)
68833 + struct listnode *node;
68834 + struct zmpls_ftn *ftn;
68836 + for (ALL_LIST_ELEMENTS_RO(&mpls_ftn_list,node,ftn))
68837 + if (index == ftn->index)
68838 + return ftn;
68840 + return NULL;
68843 +struct zmpls_ftn*
68844 +mpls_ftn_find_by_prefix(struct prefix* p)
68846 + struct listnode *node;
68847 + struct zmpls_ftn *ftn;
68849 + for (ALL_LIST_ELEMENTS_RO(&mpls_ftn_list,node,ftn))
68850 + if ((ftn->fec.type == ZEBRA_MPLS_FEC_IPV4 ||
68851 + ftn->fec.type == ZEBRA_MPLS_FEC_IPV6) &&
68852 + prefix_match(&ftn->fec.u.p, p))
68853 + return ftn;
68855 + return NULL;
68858 +struct zmpls_ftn*
68859 +mpls_ftn_find_by_fec(struct zmpls_fec* fec)
68861 + struct listnode *node;
68862 + struct zmpls_ftn *ftn;
68864 + for (ALL_LIST_ELEMENTS_RO(&mpls_ftn_list,node,ftn))
68865 + if (mpls_fec_match(fec, &ftn->fec))
68866 + return ftn;
68868 + return NULL;
68871 +static struct zmpls_ftn*
68872 +do_mpls_ftn_register(struct zmpls_ftn *ftn)
68874 + struct zmpls_ftn *new;
68876 + new = XMALLOC (MTYPE_TMP, sizeof (*new));
68877 + if (!new)
68878 + return NULL;
68880 + memcpy (new, ftn, sizeof (*new));
68882 + new->global.data = new;
68883 + new->global.next = NULL;
68884 + new->global.prev = NULL;
68886 + new->index = mpls_ftn_nextindex++;
68887 + ftn->index = new->index;
68889 + LISTNODE_ATTACH(&mpls_ftn_list, &new->global);
68890 + mpls_ctrl_ftn_register(new);
68891 + redistribute_add_mpls_ftn (new);
68892 + return new;
68895 +void
68896 +mpls_ftn_register_finish(struct zmpls_ftn *ftn, struct route_node *rn,
68897 + struct rib *rib, struct nexthop *nh)
68899 + struct nexthop *newnh;
68900 + struct zmpls_out_segment *out;
68902 + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
68904 + rib_uninstall_kernel (rn, rib);
68905 + UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
68908 + SET_FLAG (nh->flags, NEXTHOP_FLAG_IGNORE);
68909 + out = mpls_out_segment_find(ftn->out_index);
68910 + newnh = nexthop_zapi_nexthop_add(rib, &out->nh);
68911 + newnh->tied = nh;
68912 + nh->tied = newnh;
68914 + SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED_MPLS);
68915 + rib_queue_add (&zebrad, rn);
68918 +int
68919 +mpls_ftn_register(struct zmpls_ftn *ftn, int modify)
68921 + struct zmpls_out_segment *out;
68922 + struct zmpls_ftn *new;
68923 + if (!(out = mpls_out_segment_find(ftn->out_index)))
68925 + zlog_warn("mpls_ftn_register: unable to find outsegment with index %d",
68926 + ftn->out_index);
68927 + return 1;
68930 + if (!(new = do_mpls_ftn_register(ftn)))
68931 + return 1;
68933 + switch (ftn->fec.type)
68935 + case ZEBRA_MPLS_FEC_IPV4:
68936 + case ZEBRA_MPLS_FEC_IPV6:
68937 + {
68938 + struct route_node *rn = NULL;
68939 + struct nexthop *nh = NULL;
68940 + struct rib *rib = NULL;
68941 + struct nexthop nh_in;
68943 + zapi_nexthop2nexthop(&out->nh, &nh_in);
68945 + if (modify)
68947 + rib_find_nexthop(ftn->fec.owner, &ftn->fec.u.p, &nh_in,&rn,&rib,&nh);
68948 + if (rn)
68950 + mpls_ftn_register_finish(ftn, rn, rib, nh);
68951 + route_unlock_node(rn);
68952 + } else {
68953 + char str[33];
68954 + prefix2str(&ftn->fec.u.p, str, sizeof(str));
68955 + zlog_warn("mpls_ftn_register: unable to find FEC %s", str);
68957 + } else {
68958 + zlog_warn("mpls_ftn_register: modify flag not set");
68960 + break;
68962 + default:
68963 + assert(0);
68964 + break;
68966 + return 0;
68969 +static void
68970 +do_mpls_ftn_unregister(struct zmpls_ftn *ftn)
68972 + mpls_ctrl_ftn_unregister(ftn);
68974 + redistribute_delete_mpls_ftn(ftn);
68975 + LISTNODE_DETACH(&mpls_ftn_list, &ftn->global);
68976 + XFREE (MTYPE_TMP, ftn);
68979 +void
68980 +mpls_ftn_unregister_finish(struct zmpls_ftn *ftn, struct route_node *rn,
68981 + struct rib *rib, struct nexthop *nh)
68983 + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
68985 + rib_uninstall_kernel (rn, rib);
68986 + UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
68989 + if (nh->tied)
68991 + if (CHECK_FLAG (nh->flags, NEXTHOP_FLAG_IGNORE))
68993 + /* we've been handed the original non-mpls nexthop */
68994 + UNSET_FLAG (nh->flags, NEXTHOP_FLAG_IGNORE);
68995 + nexthop_delete (rib, nh->tied);
68996 + nexthop_free (nh->tied);
68997 + nh->tied = NULL;
68999 + else
69001 + /* we've been handed the mpls nexthop */
69002 + UNSET_FLAG (nh->tied->flags, NEXTHOP_FLAG_IGNORE);
69003 + nh->tied->tied = NULL;
69004 + nexthop_delete (rib, nh);
69005 + nexthop_free (nh);
69009 + SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED_MPLS);
69010 + rib_queue_add (&zebrad, rn);
69013 +void
69014 +mpls_ftn_unregister(struct zmpls_ftn *ftn, int modify)
69016 + struct zmpls_out_segment *out;
69017 + if (!(out = mpls_out_segment_find(ftn->out_index)))
69018 + return;
69020 + switch (ftn->fec.type)
69022 + case ZEBRA_MPLS_FEC_IPV4:
69023 + case ZEBRA_MPLS_FEC_IPV6:
69025 + struct route_node *rn = NULL;
69026 + struct nexthop *nh = NULL;
69027 + struct rib *rib = NULL;
69028 + struct nexthop nh_in;
69030 + zapi_nexthop2nexthop(&out->nh, &nh_in);
69032 + if (modify)
69034 + rib_find_nexthop(ftn->fec.owner, &ftn->fec.u.p, &nh_in,&rn,&rib,&nh);
69035 + if (rn)
69037 + mpls_ftn_unregister_finish(ftn, rn, rib, nh);
69038 + route_unlock_node(rn);
69041 + break;
69043 + default:
69044 + assert(0);
69045 + break;
69047 + do_mpls_ftn_unregister(ftn);
69050 +void
69051 +mpls_init (void)
69055 +void
69056 +mpls_close (void)
69058 + struct listnode *node;
69060 + while ((node = listhead (&mpls_in_segment_list)))
69061 + do_mpls_in_segment_unregister ((struct zmpls_in_segment*)listgetdata (node), 0);
69063 + while ((node = listhead (&mpls_out_segment_list)))
69064 + do_mpls_out_segment_unregister ((struct zmpls_out_segment*)listgetdata (node));
69067 +#endif /* HAVE_MPLS */
69068 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/mpls_lib.h quagga-mpls/zebra/mpls_lib.h
69069 --- quagga/zebra/mpls_lib.h 1969-12-31 18:00:00.000000000 -0600
69070 +++ quagga-mpls/zebra/mpls_lib.h 2008-02-22 22:29:28.000000000 -0600
69071 @@ -0,0 +1,206 @@
69073 + * MPLS Label Information Base for zebra daemon.
69075 + * Copyright (C) 2004 James R. Leu
69077 + * This file is part of Quagga routing suite.
69079 + * Quagga is free software; you can redistribute it and/or modify it
69080 + * under the terms of the GNU General Public License as published by the
69081 + * Free Software Foundation; either version 2, or (at your option) any
69082 + * later version.
69084 + * Quagga is distributed in the hope that it will be useful, but
69085 + * WITHOUT ANY WARRANTY; without even the implied warranty of
69086 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
69087 + * General Public License for more details.
69089 + * You should have received a copy of the GNU General Public License
69090 + * along with GNU Zebra; see the file COPYING. If not, write to the Free
69091 + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
69092 + * 02111-1307, USA.
69093 + */
69095 +#ifndef _ZEBRA_MPLS_LIB_H
69096 +#define _ZEBRA_MPLS_LIB_H
69098 +#ifdef LINUX_MPLS
69099 +#include <linux/mpls.h>
69100 +#endif
69102 +#include "zclient.h"
69103 +#include "table.h"
69104 +#include "vty.h"
69105 +#include "zebra/rib.h"
69107 +struct zmpls_in_segment
69109 + struct listnode global;
69110 + u_char installed;
69111 + u_char owner;
69112 + u_char labelspace;
69113 + u_short protocol;
69114 + u_int xc;
69115 + struct zmpls_label label;
69116 + u_char pop;
69119 +struct zmpls_out_segment
69121 + struct listnode global;
69122 + u_char installed;
69123 + u_char owner;
69124 + struct zapi_nexthop nh;
69125 + u_int index;
69126 + u_int out_key;
69129 +struct zmpls_xc
69131 + struct listnode global;
69132 + u_char installed;
69133 + u_char owner;
69134 + u_int index;
69135 + u_char in_labelspace;
69136 + struct zmpls_label in_label;
69137 + u_int out_index;
69140 +struct zmpls_ftn
69142 + struct listnode global;
69143 + u_char installed;
69144 + u_char owner;
69145 + u_int index;
69146 + struct zmpls_fec fec;
69147 + u_int out_index;
69150 +extern struct list mpls_xc_list;
69151 +extern struct list mpls_ftn_list;
69152 +extern struct list mpls_in_segment_list;
69153 +extern struct list mpls_out_segment_list;
69155 +extern int
69156 +mpls_nexthop_ready(struct zapi_nexthop *nh);
69158 +extern int
69159 +mpls_in_segment_match(struct zmpls_in_segment *a, struct zmpls_in_segment *b);
69161 +extern struct zmpls_in_segment*
69162 +mpls_in_segment_find(struct zmpls_in_segment *in);
69164 +extern int
69165 +mpls_in_segment_register(struct zmpls_in_segment *in, int install);
69167 +extern int
69168 +mpls_in_segment_unregister(struct zmpls_in_segment *in, int flag);
69170 +extern int
69171 +mpls_out_segment_register(struct zmpls_out_segment *out);
69173 +extern int
69174 +mpls_out_segment_unregister(struct zmpls_out_segment *out);
69176 +extern int
69177 +mpls_out_segment_unregister_by_index(unsigned int index);
69179 +extern int
69180 +mpls_labelspace_register(int labelspace);
69182 +extern int
69183 +mpls_labelspace_unregister(int labelspace);
69185 +extern int
69186 +mpls_labelspace_is_registered(int labelspace);
69188 +extern struct zmpls_out_segment*
69189 +mpls_out_segment_find(unsigned int index);
69191 +struct zmpls_out_segment*
69192 +mpls_out_segment_find_by_out_key(unsigned int key);
69194 +extern unsigned int
69195 +mpls_out_segment_find_index_by_nhlfe (struct zmpls_out_segment *out);
69197 +extern unsigned int
69198 +mpls_out_segment_find_index_by_nexthop(struct zapi_nexthop *nh);
69200 +extern struct zmpls_xc* mpls_xc_find (unsigned int);
69202 +extern int
69203 +mpls_xc_register (struct zmpls_xc *xc);
69205 +extern void
69206 +mpls_xc_unregister (struct zmpls_xc *xc);
69208 +extern struct zmpls_ftn* mpls_ftn_find (unsigned int);
69210 +extern struct zmpls_ftn*
69211 +mpls_ftn_find_by_fec(struct zmpls_fec* fec);
69213 +extern int
69214 +mpls_ftn_register (struct zmpls_ftn *ftn, int modify);
69216 +extern void
69217 +mpls_ftn_register_finish(struct zmpls_ftn *ftn, struct route_node *rn,
69218 + struct rib *rib, struct nexthop *nh);
69220 +extern void
69221 +mpls_ftn_unregister (struct zmpls_ftn *ftn, int modify);
69223 +extern void
69224 +mpls_ftn_unregister_finish(struct zmpls_ftn *ftn, struct route_node *rn,
69225 + struct rib *rib, struct nexthop *nh);
69227 +extern int
69228 +mpls_ctrl_init(void);
69230 +extern int
69231 +mpls_ctrl_show_hardware(struct vty *vty);
69233 +extern int
69234 +mpls_ctrl_nhlfe_unregister(struct zmpls_out_segment *old);
69236 +extern int
69237 +mpls_ctrl_nhlfe_register(struct zmpls_out_segment *new);
69239 +extern int
69240 +mpls_ctrl_ilm_unregister(struct zmpls_in_segment *old);
69242 +extern int
69243 +mpls_ctrl_ilm_register(struct zmpls_in_segment *new);
69245 +extern int
69246 +mpls_ctrl_xc_register(struct zmpls_in_segment *in,
69247 + struct zmpls_out_segment *out);
69249 +extern int
69250 +mpls_ctrl_xc_unregister(struct zmpls_in_segment *in,
69251 + struct zmpls_out_segment *out);
69253 +extern int
69254 +mpls_ctrl_ftn_register(struct zmpls_ftn *ftn);
69256 +extern int
69257 +mpls_ctrl_ftn_unregister(struct zmpls_ftn *ftn);
69259 +extern int
69260 +mpls_ctrl_set_interface_labelspace(struct interface *ifp, int labelspace);
69262 +extern int
69263 +mpls_ctrl_tunnel_register(struct interface *ifp, int update);
69265 +extern int
69266 +mpls_ctrl_tunnel_unregister(struct interface *ifp);
69268 +extern int
69269 +mpls_ctrl_read(void);
69271 +extern void
69272 +mpls_init(void);
69274 +extern void
69275 +mpls_close(void);
69277 +#endif /* _ZEBRA_MPLS_VTY_H */
69278 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/mpls_netlink.c quagga-mpls/zebra/mpls_netlink.c
69279 --- quagga/zebra/mpls_netlink.c 1969-12-31 18:00:00.000000000 -0600
69280 +++ quagga-mpls/zebra/mpls_netlink.c 2007-05-18 23:40:00.000000000 -0500
69281 @@ -0,0 +1,601 @@
69282 +#include <linux/mpls.h>
69283 +#include <linux/if_ether.h>
69284 +#include "zebra.h"
69285 +#include "debug.h"
69286 +#include "mpls_lib.h"
69287 +#include "interface.h"
69288 +#include "log.h"
69289 +#include "command.h"
69290 +#include "zebra/netlink.h"
69292 +#ifndef AF_MPLS
69293 +#define AF_MPLS 29
69294 +#endif
69296 +#ifndef NETLINK_GENERIC
69297 +#define NETLINK_GENERIC 16
69298 +#endif
69300 +/* Socket interface to kernel */
69301 +struct nlsock
69302 + mpls_netlink = {-1,0,{0},"mpls-netlink-listen",0},/* kernel messages */
69303 + mpls_netlink_cmd = {-1,0,{0},"mpls-netlink-cmd",1}, /* command channel */
69304 + mpls_netlink_nhlfe= {-1,0,{0},"mpls-netlink-nhlfe",1}; /* nhlfe adds */
69306 +int
69307 +mpls_ctrl_show_hardware(struct vty *vty)
69309 + vty_out(vty, "MPLS-Linux: %d.%d%d%d netlink control%s",
69310 + (MPLS_LINUX_VERSION >> 24) & 0xFF,
69311 + (MPLS_LINUX_VERSION >> 16) & 0xFF,
69312 + (MPLS_LINUX_VERSION >> 8) & 0xFF,
69313 + (MPLS_LINUX_VERSION) & 0xFF, VTY_NEWLINE);
69314 + return CMD_SUCCESS;
69317 +int
69318 +mpls_ctrl_nhlfe_unregister(struct zmpls_out_segment *old)
69320 + struct genlmsghdr *ghdr;
69321 + struct
69323 + struct nlmsghdr n;
69324 + char buf[4096];
69325 + } req;
69326 + struct mpls_out_label_req mol;
69328 + memset (&req, 0, sizeof(req));
69329 + memset (&mol, 0, sizeof(mol));
69331 + req.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
69332 + req.n.nlmsg_flags = NLM_F_CREATE|NLM_F_REQUEST;
69333 + req.n.nlmsg_type = AF_MPLS;
69335 + ghdr = NLMSG_DATA(&req.n);
69336 + ghdr->cmd = MPLS_CMD_DELNHLFE;
69338 + mol.mol_label.ml_type = MPLS_LABEL_KEY;
69339 + mol.mol_label.u.ml_key = old->out_key;
69341 + addattr_l(&req.n, sizeof(req), MPLS_ATTR_NHLFE, &mol, sizeof(mol));
69343 + return netlink_talk (&req.n, &mpls_netlink_cmd, NULL, 0);
69346 +int
69347 +mpls_ctrl_nhlfe_register(struct zmpls_out_segment *new)
69349 + struct genlmsghdr *ghdr;
69350 + struct
69352 + struct nlmsghdr n;
69353 + char buf[4096];
69354 + } req, res;
69356 + struct mpls_out_label_req mol, *molp;
69357 + struct mpls_instr_req mir;
69358 + struct rtattr *tb[MPLS_ATTR_MAX + 1];
69359 + struct rtattr *attrs;
69360 + int result;
69362 + memset (&req, 0, sizeof(req));
69363 + memset (&res, 0, sizeof(res));
69364 + memset (&mol, 0, sizeof(mol));
69365 + memset (&mir, 0, sizeof(mir));
69367 + req.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
69368 + req.n.nlmsg_flags = NLM_F_CREATE|NLM_F_REQUEST;
69369 + req.n.nlmsg_type = AF_MPLS;
69371 + ghdr = NLMSG_DATA(&req.n);
69372 + ghdr->cmd = MPLS_CMD_NEWNHLFE;
69374 + mol.mol_label.ml_type = MPLS_LABEL_KEY;
69375 + mol.mol_label.u.ml_key = 0;
69376 + mol.mol_change_flag |= MPLS_CHANGE_INSTR;
69378 + mir.mir_direction = MPLS_OUT;
69379 + memcpy(&mir.mir_label,&mol.mol_label,sizeof(struct mpls_label));
69381 + mir.mir_instr[0].mir_opcode = MPLS_OP_PUSH;
69382 + mir.mir_instr[0].mir_data.push.ml_type = MPLS_LABEL_GEN;
69383 + mir.mir_instr[0].mir_data.push.u.ml_gen = new->nh.mpls.u.gen;
69385 + mir.mir_instr[1].mir_opcode = MPLS_OP_SET;
69387 + if (CHECK_FLAG (new->nh.type, ZEBRA_NEXTHOP_IFNAME))
69389 + struct interface *ifp = if_lookup_by_name (new->nh.intf.name);
69390 + mir.mir_instr[1].mir_data.set.mni_if = ifp ? ifp->ifindex : 0;
69393 + if (CHECK_FLAG (new->nh.type, ZEBRA_NEXTHOP_IPV4))
69395 + struct sockaddr_in addr;
69396 + addr.sin_family = AF_INET;
69397 + addr.sin_addr = new->nh.gw.ipv4;
69398 + memcpy(&mir.mir_instr[1].mir_data.set.mni_addr, &addr, sizeof(addr));
69400 + else if (CHECK_FLAG (new->nh.type, ZEBRA_NEXTHOP_IPV6))
69402 + struct sockaddr_in6 addr;
69403 + addr.sin6_family = AF_INET6;
69404 + addr.sin6_addr = new->nh.gw.ipv6;
69405 + memcpy(&mir.mir_instr[1].mir_data.set.mni_addr, &addr, sizeof(addr));
69407 + else
69409 + assert (0);
69412 + mir.mir_instr_length = 2;
69414 + addattr_l(&req.n, sizeof(req), MPLS_ATTR_NHLFE, &mol, sizeof(mol));
69415 + addattr_l(&req.n, sizeof(req), MPLS_ATTR_INSTR, &mir, sizeof(mir));
69417 + result = netlink_talk (&req.n, &mpls_netlink_nhlfe, (void*)&res, sizeof(res));
69419 + ghdr = NLMSG_DATA(&res.n);
69420 + attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN);
69421 + netlink_parse_rtattr(tb, MPLS_ATTR_MAX, attrs,
69422 + res.n.nlmsg_len - NLMSG_LENGTH(GENL_HDRLEN));
69423 + molp = RTA_DATA(tb[MPLS_ATTR_NHLFE]);
69425 + new->out_key = molp->mol_label.u.ml_key;
69426 + zlog(NULL, LOG_ERR, "mpls_ctrl_nhlfe_register(): "
69427 + "NHLFE 0x%08x", new->out_key);
69428 + return result;
69431 +static int do_ilm(int cmd, struct zmpls_in_segment *ilm)
69433 + struct genlmsghdr *ghdr;
69434 + struct
69436 + struct nlmsghdr n;
69437 + char buf[4096];
69438 + } req;
69439 + struct mpls_in_label_req mil;
69441 + memset (&req, 0, sizeof(req));
69442 + memset (&mil, 0, sizeof(mil));
69444 + req.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
69445 + req.n.nlmsg_flags = NLM_F_CREATE|NLM_F_REQUEST;
69446 + req.n.nlmsg_type = AF_MPLS;
69448 + ghdr = NLMSG_DATA(&req.n);
69449 + ghdr->cmd = cmd;
69451 + mil.mil_proto = AF_INET;
69452 + mil.mil_label.ml_type = MPLS_LABEL_GEN;
69453 + mil.mil_label.u.ml_gen = ilm->label.u.gen;
69454 + mil.mil_label.ml_index = ilm->labelspace;
69456 + addattr_l(&req.n, sizeof(req), MPLS_ATTR_ILM, &mil, sizeof(mil));
69458 + return netlink_talk (&req.n, &mpls_netlink_cmd, NULL, 0);
69461 +int
69462 +mpls_ctrl_ilm_unregister(struct zmpls_in_segment *old)
69464 + return do_ilm(MPLS_CMD_DELILM, old);
69467 +int
69468 +mpls_ctrl_ilm_register(struct zmpls_in_segment *new)
69470 + return do_ilm(MPLS_CMD_NEWILM, new);
69473 +static int do_xc(int cmd, struct zmpls_in_segment *in,
69474 + struct zmpls_out_segment *out)
69476 + struct genlmsghdr *ghdr;
69477 + struct
69479 + struct nlmsghdr n;
69480 + char buf[4096];
69481 + } req;
69482 + struct mpls_xconnect_req mx;
69484 + memset (&req, 0, sizeof(req));
69485 + memset (&mx, 0, sizeof(mx));
69487 + req.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
69488 + req.n.nlmsg_flags = NLM_F_CREATE|NLM_F_REQUEST;
69489 + req.n.nlmsg_type = AF_MPLS;
69491 + ghdr = NLMSG_DATA(&req.n);
69492 + ghdr->cmd = cmd;
69494 + mx.mx_in.ml_type = MPLS_LABEL_GEN;
69495 + mx.mx_in.u.ml_gen = in->label.u.gen;
69496 + mx.mx_in.ml_index = in->labelspace;
69497 + mx.mx_out.ml_type = MPLS_LABEL_KEY;
69498 + mx.mx_out.u.ml_key = out->out_key;
69500 + addattr_l(&req.n, sizeof(req), MPLS_ATTR_XC, &mx, sizeof(mx));
69502 + return netlink_talk (&req.n, &mpls_netlink_cmd, NULL, 0);
69505 +int mpls_ctrl_xc_register(struct zmpls_in_segment *in,
69506 + struct zmpls_out_segment *out)
69508 + return do_xc(MPLS_CMD_NEWXC, in, out);
69511 +int mpls_ctrl_xc_unregister(struct zmpls_in_segment *in,
69512 + struct zmpls_out_segment *out)
69514 + return do_xc(MPLS_CMD_DELXC, in, out);
69517 +int mpls_ctrl_ftn_register(struct zmpls_ftn *ftn)
69519 + return 0;
69522 +int mpls_ctrl_ftn_unregister(struct zmpls_ftn *ftn)
69524 + return 0;
69527 +int mpls_ctrl_tunnel_register(struct interface *ifp, int update)
69529 +#if 0
69530 + struct zebra_if *if_data = ifp->info;
69531 + struct
69533 + struct nlmsghdr n;
69534 + struct mpls_tunnel_req mt;
69535 + char buf[1024];
69536 + } req;
69538 + memset (&req, 0, sizeof(req));
69539 + req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct mpls_tunnel_req));
69540 + req.n.nlmsg_flags = NLM_F_REQUEST;
69541 + if (update)
69543 + req.n.nlmsg_flags |= NLM_F_APPEND;
69544 + req.mt.mt_nhlfe_key = (int)if_data->ops->info;
69546 + else
69548 + req.n.nlmsg_flags |= NLM_F_CREATE;
69551 + req.n.nlmsg_type = MPLS_RTM_ADDTUNNEL;
69553 + strncpy(req.mt.mt_ifname, ifp->name, IFNAMSIZ);
69555 + return netlink_talk (&req.n, &netlink_cmd, NULL, 0);
69556 +#else
69557 + return 0;
69558 +#endif
69561 +int mpls_ctrl_tunnel_unregister(struct interface *ifp)
69563 +#if 0
69564 + struct genlmsghdr *ghdr;
69565 + struct
69567 + struct nlmsghdr n;
69568 + char buf[1024];
69569 + } req;
69570 + struct mpls_labelspace_req ls;
69572 + memset (&req, 0, sizeof(req));
69573 + memset (&ls, 0, sizeof(ls));
69575 + req.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
69576 + req.n.nlmsg_flags = NLM_F_CREATE|NLM_F_REQUEST;
69577 + req.n.nlmsg_type = AF_MPLS;
69579 + ghdr = NLMSG_DATA(&req.n);
69580 + ghdr->cmd = MPLS_CMD_SETLABELSPACE;
69581 + struct
69583 + struct nlmsghdr n;
69584 + struct mpls_tunnel_req mt;
69585 + char buf[1024];
69586 + } req;
69588 + memset (&req, 0, sizeof(req));
69589 + req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct mpls_tunnel_req));
69590 + req.n.nlmsg_flags = NLM_F_CREATE|NLM_F_REQUEST;
69591 + req.n.nlmsg_type = MPLS_RTM_DELTUNNEL;
69593 + req.mt.mt_nhlfe_key = 0;
69594 + strncpy(req.mt.mt_ifname, ifp->name, IFNAMSIZ);
69596 + return netlink_talk (&req.n, &netlink_cmd, NULL, 0);
69597 +#else
69598 + return 0;
69599 +#endif
69602 +int mpls_ctrl_set_interface_labelspace(struct interface *ifp, int labelspace)
69604 + struct genlmsghdr *ghdr;
69605 + struct
69607 + struct nlmsghdr n;
69608 + char buf[1024];
69609 + } req;
69610 + struct mpls_labelspace_req ls;
69612 + memset (&req, 0, sizeof(req));
69613 + memset (&ls, 0, sizeof(ls));
69615 + req.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
69616 + req.n.nlmsg_flags = NLM_F_CREATE|NLM_F_REQUEST;
69617 + req.n.nlmsg_type = AF_MPLS;
69619 + ghdr = NLMSG_DATA(&req.n);
69620 + ghdr->cmd = MPLS_CMD_SETLABELSPACE;
69622 + ls.mls_labelspace = (labelspace < 0) ? -1 : labelspace;
69623 + ls.mls_ifindex = ifp->ifindex;
69625 + addattr_l(&req.n, sizeof(req), MPLS_ATTR_LABELSPACE, &ls, sizeof(ls));
69627 + return netlink_talk (&req.n, &mpls_netlink_cmd, NULL, 0);
69630 +static int
69631 +mpls_netlink_information_fetch (struct nlsock *nl, struct sockaddr_nl *snl, struct nlmsghdr *h)
69633 + struct rtattr *tb[MPLS_ATTR_MAX + 1];
69634 + struct genlmsghdr *ghdr = NLMSG_DATA(h);
69635 + int len = h->nlmsg_len;
69636 + struct rtattr *attrs;
69638 + /* skip unsolicited messages originating from command socket */
69639 + if (!nl->cmd)
69641 + struct nlsock *tmp = NULL;
69643 + if (h->nlmsg_pid == mpls_netlink_cmd.snl.nl_pid)
69644 + tmp = &mpls_netlink_cmd;
69645 + else if (h->nlmsg_pid == mpls_netlink_nhlfe.snl.nl_pid)
69646 + tmp = &mpls_netlink_nhlfe;
69648 + if (tmp)
69650 + if (IS_ZEBRA_DEBUG_KERNEL)
69651 + zlog_debug ("netlink_parse_info: %s packet comes from %s",
69652 + tmp->name, nl->name);
69653 + return 0;
69657 + if (h->nlmsg_type != AF_MPLS) {
69658 + zlog_warn ("Invalid mpls-netlink nlmsg_type %d\n", h->nlmsg_type);
69659 + return 0;
69662 + len -= NLMSG_LENGTH(GENL_HDRLEN);
69663 + if (len < 0) {
69664 + zlog_warn ("Invalid mpls-netlink nlmsg length %d\n", len);
69665 + return 0;
69668 + attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN);
69669 + netlink_parse_rtattr(tb, MPLS_ATTR_MAX, attrs, len);
69671 + switch (ghdr->cmd)
69673 + case MPLS_CMD_NEWNHLFE:
69674 + case MPLS_CMD_DELNHLFE:
69676 + struct mpls_out_label_req *molr = RTA_DATA(tb[MPLS_ATTR_NHLFE]);
69677 + struct mpls_instr_req *mir = RTA_DATA(tb[MPLS_ATTR_INSTR]);
69678 + struct zmpls_out_segment out;
69679 + int i;
69681 + out.owner = ZEBRA_ROUTE_KERNEL;
69682 + out.out_key = molr->mol_label.u.ml_key;
69684 + for (i = 0;i < mir->mir_instr_length;i++)
69686 + if (mir->mir_instr[i].mir_opcode == MPLS_OP_PUSH)
69688 + out.nh.mpls.u.gen = mir->mir_instr[i].mir_push.u.ml_gen;
69689 + out.nh.mpls.type = ZEBRA_MPLS_LABEL_GEN;
69692 + if (mir->mir_instr[i].mir_opcode == MPLS_OP_SET)
69694 + struct interface *ifp;
69695 + struct sockaddr_in *saddr;
69697 + saddr = (struct sockaddr_in*)&mir->mir_instr[i].mir_set.mni_addr;
69698 + ifp = if_lookup_by_index(mir->mir_instr[i].mir_set.mni_if);
69699 + strncpy(out.nh.intf.name, ifp->name, IFNAMSIZ);
69700 + out.nh.gw.ipv4.s_addr = saddr->sin_addr.s_addr;
69701 + SET_FLAG (out.nh.type, ZEBRA_NEXTHOP_IPV4);
69702 + SET_FLAG (out.nh.type, ZEBRA_NEXTHOP_IFNAME);
69705 + if (ghdr->cmd == MPLS_CMD_NEWNHLFE) {
69706 + if (mpls_out_segment_find_by_out_key(out.out_key))
69707 + return 0;
69708 + if (mir->mir_instr_length == 2)
69709 + mpls_out_segment_register(&out);
69710 + } else {
69711 + if (!mpls_out_segment_find_by_out_key(out.out_key))
69712 + return 0;
69713 + mpls_out_segment_unregister(&out);
69715 + break;
69717 + case MPLS_CMD_NEWILM:
69718 + case MPLS_CMD_DELILM:
69720 + struct mpls_in_label_req *milr = RTA_DATA(tb[MPLS_ATTR_ILM]);
69721 + struct zmpls_in_segment in;
69723 + in.labelspace = milr->mil_label.ml_index;
69724 + in.label.type = ZEBRA_MPLS_LABEL_GEN;
69725 + in.label.u.gen = milr->mil_label.u.ml_gen;
69726 + in.protocol = milr->mil_proto;
69727 + in.owner = ZEBRA_ROUTE_KERNEL;
69728 + in.pop = 1;
69730 + if (ghdr->cmd == MPLS_CMD_NEWILM) {
69731 + if (mpls_in_segment_find(&in))
69732 + return 0;
69733 + mpls_in_segment_register(&in, 0);
69734 + } else {
69735 + if (!mpls_in_segment_find(&in))
69736 + return 0;
69737 + mpls_in_segment_unregister(&in, 0);
69739 + break;
69741 + case MPLS_CMD_NEWXC:
69742 + case MPLS_CMD_DELXC:
69744 + struct mpls_xconnect_req *mxr = RTA_DATA(tb[MPLS_ATTR_XC]);
69745 + struct zmpls_out_segment *out;
69746 + struct zmpls_in_segment tmp;
69747 + struct zmpls_in_segment *in;
69748 + struct zmpls_xc xc;
69750 + tmp.labelspace = mxr->mx_in.ml_index;
69751 + tmp.label.type = ZEBRA_MPLS_LABEL_GEN;
69752 + tmp.label.u.gen = mxr->mx_in.u.ml_gen;
69754 + out = mpls_out_segment_find_by_out_key(mxr->mx_out.u.ml_key);
69755 + in = mpls_in_segment_find (&tmp);
69757 + xc.in_labelspace = in->labelspace;
69758 + memcpy(&xc.in_label, &in->label, sizeof(struct zmpls_label));
69759 + xc.out_index = out->index;
69761 + if (ghdr->cmd == MPLS_CMD_NEWXC) {
69762 + if (in->xc)
69763 + return 0;
69764 + mpls_xc_register(&xc);
69765 + } else {
69766 + if (!in->xc)
69767 + return 0;
69768 + mpls_xc_unregister(&xc);
69770 + break;
69772 + case MPLS_CMD_SETLABELSPACE:
69774 + struct mpls_labelspace_req *mlr = RTA_DATA(tb[MPLS_ATTR_LABELSPACE]);
69775 + struct interface *ifp;
69777 + ifp = if_lookup_by_index(mlr->mls_ifindex);
69778 + if (ifp)
69779 + ifp->mpls_labelspace = mlr->mls_labelspace;
69781 + break;
69783 + default:
69784 + zlog_warn ("Unknown mpls-netlink cmd %d\n", ghdr->cmd);
69785 + break;
69787 + return 0;
69790 +void
69791 +mpls_read (void)
69793 +#if 0
69794 + int ret;
69795 + int flags;
69796 + int snb_ret;
69798 + /*
69799 + * Change netlink socket flags to blocking to ensure we get
69800 + * a reply via nelink_parse_info
69801 + */
69802 + snb_ret = set_netlink_blocking (&mpls_netlink_cmd, &flags);
69803 + if (snb_ret < 0)
69804 + zlog (NULL, LOG_WARNING,
69805 + "%s:%i Warning: Could not set netlink socket to blocking.",
69806 + __FUNCTION__, __LINE__);
69808 + /* Get NHLFE entries. */
69809 + ret = genetlink_request (AF_MPLS, MPLS_CMD_GETNHLFE, &mpls_netlink_cmd);
69810 + if (ret < 0)
69811 + return;
69812 + ret = netlink_parse_info (mpls_netlink_information_fetch,
69813 + &mpls_netlink_cmd, NULL, 0);
69814 + if (ret < 0)
69815 + return;
69817 + /* Get ILM entries */
69818 + ret = genetlink_request (AF_MPLS, MPLS_CMD_GETILM, &mpls_netlink_cmd);
69819 + if (ret < 0)
69820 + return;
69821 + ret = netlink_parse_info (mpls_netlink_information_fetch,
69822 + &mpls_netlink_cmd, NULL, 0);
69823 + if (ret < 0)
69824 + return;
69826 + /* Get LABELSPACE entries */
69827 + ret = netlink_request (AF_MPLS, MPLS_CMD_GETLABELSPACE, &mpls_netlink_cmd);
69828 + if (ret < 0)
69829 + return;
69830 + ret = netlink_parse_info (mpls_netlink_information_fetch,
69831 + &mpls_netlink_cmd, NULL, 0);
69832 + if (ret < 0)
69833 + return;
69835 + /* Get XC entries */
69836 + ret = netlink_request (AF_MPLS, MPLS_CMD_GETXC, &mpls_netlink_cmd);
69837 + if (ret < 0)
69838 + return;
69839 + ret = netlink_parse_info (mpls_netlink_information_fetch,
69840 + &mpls_netlink_cmd, NULL, 0);
69841 + if (ret < 0)
69842 + return;
69844 + /* restore flags */
69845 + if (snb_ret == 0)
69846 + set_netlink_nonblocking (&mpls_netlink_cmd, &flags);
69847 +#endif
69850 +extern struct thread_master *master;
69852 +/* Kernel route reflection. */
69853 +static int
69854 +mpls_kernel_read (struct thread *thread)
69856 + int ret;
69857 + int sock;
69859 + sock = THREAD_FD (thread);
69860 + ret = netlink_parse_info (mpls_netlink_information_fetch,
69861 + &mpls_netlink, NULL, 0);
69862 + thread_add_read (zebrad.master, mpls_kernel_read, NULL, mpls_netlink.sock);
69864 + return 0;
69867 +/* Exported interface function. This function simply calls
69868 + netlink_socket (). */
69869 +void
69870 +mpls_kernel_init ()
69872 + unsigned long groups;
69874 + groups = MPLS_GRP_NHLFE | MPLS_GRP_ILM | MPLS_GRP_XC | MPLS_GRP_LABELSPACE;
69875 + netlink_socket (&mpls_netlink, NETLINK_GENERIC, groups);
69876 + netlink_socket (&mpls_netlink_cmd, NETLINK_GENERIC, 0);
69877 + netlink_socket (&mpls_netlink_nhlfe, NETLINK_GENERIC, MPLS_GRP_NHLFE);
69879 + /* Register kernel socket. */
69880 + if (mpls_netlink.sock > 0)
69881 + thread_add_read (zebrad.master, mpls_kernel_read, NULL, mpls_netlink.sock);
69883 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/mpls_null.c quagga-mpls/zebra/mpls_null.c
69884 --- quagga/zebra/mpls_null.c 1969-12-31 18:00:00.000000000 -0600
69885 +++ quagga-mpls/zebra/mpls_null.c 2008-02-22 22:09:28.000000000 -0600
69886 @@ -0,0 +1,82 @@
69887 +#include <zebra.h>
69888 +#include "command.h"
69889 +#include "mpls_lib.h"
69891 +void
69892 +mpls_kernel_init()
69896 +int
69897 +mpls_ctrl_show_hardware(struct vty *vty)
69899 + vty_out(vty, "MPLS Null driver%s", VTY_NEWLINE);
69900 + return CMD_SUCCESS;
69904 +int
69905 +mpls_ctrl_nhlfe_unregister(struct zmpls_out_segment *old)
69907 + return 0;
69910 +int
69911 +mpls_ctrl_nhlfe_register(struct zmpls_out_segment *new)
69913 + return 0;
69916 +int
69917 +mpls_ctrl_ilm_unregister(struct zmpls_in_segment *old)
69919 + return 0;
69922 +int
69923 +mpls_ctrl_ilm_register(struct zmpls_in_segment *new)
69925 + return 0;
69928 +int mpls_ctrl_set_interface_labelspace(struct interface *ifp, int labelspace)
69930 + return 0;
69933 +int mpls_ctrl_xc_register(struct zmpls_in_segment *in,
69934 + struct zmpls_out_segment *out)
69936 + return 0;
69939 +int mpls_ctrl_xc_unregister(struct zmpls_in_segment *in,
69940 + struct zmpls_out_segment *out)
69942 + return 0;
69945 +int mpls_ctrl_ftn_register(struct zmpls_ftn *ftn)
69947 + return 0;
69950 +int mpls_ctrl_ftn_unregister(struct zmpls_ftn *ftn)
69952 + return 0;
69955 +int mpls_ctrl_tunnel_register(struct interface *ifp, int update)
69957 + return 0;
69960 +int mpls_ctrl_tunnel_unregister(struct interface *ifp)
69962 + return 0;
69965 +int mpls_read(void)
69967 + return 0;
69969 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/mpls_vty.c quagga-mpls/zebra/mpls_vty.c
69970 --- quagga/zebra/mpls_vty.c 1969-12-31 18:00:00.000000000 -0600
69971 +++ quagga-mpls/zebra/mpls_vty.c 2007-05-18 23:32:32.000000000 -0500
69972 @@ -0,0 +1,738 @@
69974 + * MPLS CLI for zebra daemon.
69976 + * Copyright (C) 2004 James R. Leu
69978 + * This file is part of Quagga routing suite.
69980 + * Quagga is free software; you can redistribute it and/or modify it
69981 + * under the terms of the GNU General Public License as published by the
69982 + * Free Software Foundation; either version 2, or (at your option) any
69983 + * later version.
69985 + * Quagga is distributed in the hope that it will be useful, but
69986 + * WITHOUT ANY WARRANTY; without even the implied warranty of
69987 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
69988 + * General Public License for more details.
69990 + * You should have received a copy of the GNU General Public License
69991 + * along with GNU Zebra; see the file COPYING. If not, write to the Free
69992 + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
69993 + * 02111-1307, USA.
69994 + */
69996 +#include <zebra.h>
69998 +#ifdef HAVE_MPLS
70000 +#include "zclient.h"
70001 +#include "vty.h"
70002 +#include "linklist.h"
70003 +#include "memory.h"
70004 +#include "command.h"
70005 +#include "mpls_lib.h"
70006 +#include "if.h"
70007 +#include "connected.h"
70008 +#include "interface.h"
70009 +#include "ioctl.h"
70010 +#include "zserv.h"
70011 +#include "router-id.h"
70012 +#include "mpls_vty.h"
70014 +static
70015 +int label_parse(struct vty *vty, const char **argv, struct zmpls_label *label)
70017 + if (!strncmp(argv[0], "gen", 3))
70019 + label->type = ZEBRA_MPLS_LABEL_GEN;
70021 + else if (!strncmp(argv[0], "atm", 3))
70023 + label->type = ZEBRA_MPLS_LABEL_ATM;
70025 + else if (!strncmp(argv[0], "fr", 2))
70027 + label->type = ZEBRA_MPLS_LABEL_FR;
70029 + else
70031 + vty_out (vty, "'%s' is not a valid label type (gen|atm|fr)%s",
70032 + argv[0], VTY_NEWLINE);
70033 + return CMD_WARNING;
70036 + switch (label->type)
70038 + case ZEBRA_MPLS_LABEL_GEN:
70039 + if ((!sscanf(argv[1], "%u", &label->u.gen)))
70041 + vty_out (vty, "'%s' is not an valid gen label value (16 .. 2^20 - 1)%s",
70042 + argv[1], VTY_NEWLINE);
70043 + return CMD_WARNING;
70045 + break;
70046 + case ZEBRA_MPLS_LABEL_ATM:
70047 + if ((sscanf(argv[1], "%hu/%hu", &label->u.atm.vpi,
70048 + &label->u.atm.vci) != 2))
70050 + vty_out (vty, "'%s' is not an valid atm label value (vpi/vci)%s",
70051 + argv[1], VTY_NEWLINE);
70052 + return CMD_WARNING;
70054 + break;
70055 + case ZEBRA_MPLS_LABEL_FR:
70056 + if ((!sscanf(argv[1], "%u", &label->u.fr)))
70058 + vty_out (vty, "'%s' is not an valid fr label value (1 .. 2^17 - 1)%s",
70059 + argv[1], VTY_NEWLINE);
70060 + return CMD_WARNING;
70062 + break;
70064 + return CMD_SUCCESS;
70067 +int
70068 +nhlfe_parse(struct vty *vty, const char **argv, struct zmpls_out_segment *out,
70069 + const char* addr)
70071 + struct prefix p;
70072 + int result;
70074 + result = label_parse (vty, argv, &out->nh.mpls);
70075 + if (result != CMD_SUCCESS)
70076 + return result;
70078 + strncpy(out->nh.intf.name, argv[2], IFNAMSIZ);
70079 + SET_FLAG (out->nh.type, ZEBRA_NEXTHOP_IFNAME);
70081 + if (addr)
70083 + str2prefix (addr, &p);
70084 + if ((p.family == AF_INET && p.prefixlen != IPV4_MAX_BITLEN) ||
70085 + (p.family == AF_INET6 && p.prefixlen != IPV6_MAX_BITLEN))
70087 + vty_out (vty, "Nexthop IP address must be a host address(%s)%s",
70088 + addr, VTY_NEWLINE);
70089 + return CMD_WARNING;
70091 + switch (p.family)
70093 + case AF_INET:
70094 + if (p.prefixlen != IPV4_MAX_BITLEN)
70096 + vty_out (vty, "Nexthop IP address must be a host address(%s)%s",
70097 + addr, VTY_NEWLINE);
70098 + return CMD_WARNING;
70100 + out->nh.gw.ipv4 = p.u.prefix4;
70101 + SET_FLAG (out->nh.type, ZEBRA_NEXTHOP_IPV4);
70102 + break;
70103 + case AF_INET6:
70104 + if (p.prefixlen != IPV6_MAX_BITLEN)
70105 + {
70106 + vty_out (vty, "Nexthop IP address must be a host address(%s)%s",
70107 + addr, VTY_NEWLINE);
70108 + return CMD_WARNING;
70110 + out->nh.gw.ipv6 = p.u.prefix6;
70111 + SET_FLAG (out->nh.type, ZEBRA_NEXTHOP_IPV6);
70112 + break;
70113 + default:
70114 + vty_out (vty, "Invalid nexthop(%s)%s", addr, VTY_NEWLINE);
70115 + return CMD_WARNING;
70116 + break;
70119 + return CMD_SUCCESS;
70122 +/******************************** vty commands ******************************/
70124 +DEFUN (mpls_static_num,
70125 + mpls_static_num_cmd,
70126 + "mpls static <0-255>",
70127 + "Multi-protocol Label Switching\n"
70128 + "Static label information base\n"
70129 + "Labelspace number\n")
70131 + int labelspace = -1;
70132 + if (!sscanf(argv[0], "%u", &labelspace)) {
70133 + vty_out (vty, "'%s' is not an valid labelspace (0 .. 255)%s",
70134 + argv[0], VTY_NEWLINE);
70135 + return CMD_WARNING;
70137 + vty->index = (void*)labelspace;
70138 + vty->node = MPLS_LABELSPACE_NODE;
70139 + return CMD_SUCCESS;
70142 +DEFUN (no_mpls_static_num,
70143 + no_mpls_static_num_cmd,
70144 + "no mpls static <0-255>",
70145 + NO_STR
70146 + "Multi-protocol Label Switching\n"
70147 + "Static labeling information\n"
70148 + "Labelspace number\n")
70150 + struct listnode *node;
70151 + struct listnode *nnode;
70152 + struct zmpls_in_segment *in;
70153 + int labelspace = -1;
70155 + if (!sscanf(argv[0], "%u", &labelspace)) {
70156 + vty_out (vty, "'%s' is not an valid labelspace (0 .. 255)%s",
70157 + argv[0], VTY_NEWLINE);
70158 + return CMD_WARNING;
70161 + for (ALL_LIST_ELEMENTS(&mpls_in_segment_list, node, nnode, in))
70162 + if (in->labelspace == labelspace)
70163 + mpls_in_segment_unregister(in, 1);
70165 + return CMD_SUCCESS;
70168 +DEFUN (label_map_pop,
70169 + label_map_pop_cmd,
70170 + "label-map (gen|atm|fr) VALUE pop",
70171 + "Create a static incoming label-map (ILM)\n"
70172 + "In-coming Generic label\n"
70173 + "In-coming ATM VC\n"
70174 + "In-coming FR DLCI\n"
70175 + "Label value\n"
70176 + "Pop and lookup\n")
70178 + struct zmpls_in_segment in;
70179 + int result;
70181 + in.owner = ZEBRA_ROUTE_STATIC;
70182 + in.labelspace = (int)vty->index;
70184 + result = label_parse(vty,argv,&in.label);
70185 + if (result != CMD_SUCCESS)
70186 + return result;
70188 + in.pop = 1;
70190 + return mpls_in_segment_register(&in, 1) ? CMD_WARNING : CMD_SUCCESS;
70193 +static int
70194 +create_ilm_xc_nhlfe(struct vty *vty, const char **ilm, const char **nhlfe,
70195 + const char *addr)
70197 + struct zmpls_in_segment in;
70198 + struct zmpls_out_segment out;
70199 + struct zmpls_xc xc;
70200 + int result;
70202 + in.owner = ZEBRA_ROUTE_STATIC;
70204 + in.labelspace = (int)vty->index;
70206 + result = label_parse (vty, ilm, &in.label);
70207 + if (result != CMD_SUCCESS)
70208 + return result;
70210 + memset (&out, 0, sizeof (out));
70211 + out.owner = ZEBRA_ROUTE_STATIC;
70212 + result = nhlfe_parse (vty, nhlfe, &out, addr);
70213 + if (result != CMD_SUCCESS)
70214 + return result;
70216 + if (mpls_out_segment_find_index_by_nhlfe(&out))
70218 + vty_out(vty, "NHLFE already exists%s",VTY_NEWLINE);
70219 + goto error_out;
70222 + out.index = 0;
70223 + if (mpls_out_segment_register (&out))
70225 + vty_out(vty, "Unable to register NHLFE%s",VTY_NEWLINE);
70226 + goto error_out;
70229 + in.pop = 1;
70230 + if (mpls_in_segment_register (&in, (out.installed)))
70232 + goto error_in;
70235 + xc.in_labelspace = in.labelspace;
70236 + memcpy(&xc.in_label, &in.label, sizeof(struct zmpls_label));
70237 + xc.out_index = out.index;
70239 + if (mpls_xc_register (&xc))
70241 + goto error_xc;
70243 + return CMD_SUCCESS;
70245 +error_xc:
70246 + mpls_in_segment_unregister (&in, 1);
70248 +error_in:
70249 + mpls_out_segment_unregister (&out);
70251 +error_out:
70252 + return CMD_WARNING;
70255 +DEFUN (label_map_swap_if,
70256 + label_map_swap_if_cmd,
70257 + "label-map (gen|atm|fr) VALUE swap (gen|atm|fr) VALUE nexthop INTERFACE",
70258 + "Create a static incoming label-map (ILM)\n"
70259 + "In-coming Generic label\n"
70260 + "In-coming ATM VC\n"
70261 + "In-coming FR DLCI\n"
70262 + "Label value\n"
70263 + "Forward\n"
70264 + "Out-going Generic label\n"
70265 + "Out-going ATM VC\n"
70266 + "Out-going FR DLCI\n"
70267 + "Label value\n"
70268 + "Nexthop\n"
70269 + "Out-going interface name\n")
70271 + return create_ilm_xc_nhlfe(vty, argv, &argv[2], NULL);
70274 +DEFUN (label_map_swap_if_addr,
70275 + label_map_swap_if_addr_cmd,
70276 + "label-map (gen|atm|fr) VALUE swap (gen|atm|fr) VALUE nexthop INTERFACE IPADDR",
70277 + "Incoming label-map (ILM)\n"
70278 + "In-coming Generic label\n"
70279 + "In-coming ATM VC\n"
70280 + "In-coming FR DLCI\n"
70281 + "Label value\n"
70282 + "Forward\n"
70283 + "Out-going Generic label\n"
70284 + "Out-going ATM VC\n"
70285 + "Out-going FR DLCI\n"
70286 + "Label value\n"
70287 + "Nexthop\n"
70288 + "Out-going interface name\n"
70289 + "Nexthop IP address\n")
70291 + return create_ilm_xc_nhlfe(vty, argv, &argv[2], argv[5]);
70294 +DEFUN (no_label_map,
70295 + no_label_map_cmd,
70296 + "no label-map (gen|atm|fr) VALUE",
70297 + NO_STR
70298 + "Incoming label-map (ILM)\n"
70299 + "In-coming Generic label\n"
70300 + "In-coming ATM VC\n"
70301 + "In-coming FR DLCI\n"
70302 + "Label value\n")
70304 + struct zmpls_in_segment in;
70305 + int result;
70307 + in.labelspace = (int)vty->index;
70309 + result = label_parse(vty, argv, &in.label);
70310 + if (result != CMD_SUCCESS)
70311 + return result;
70313 + return mpls_in_segment_unregister(&in, 1) ? CMD_WARNING : CMD_SUCCESS;
70316 +static void
70317 +mpls_interface_show_write (struct vty *vty, struct interface *ifp)
70319 + struct zebra_if *if_data;
70320 + if_data = ifp->info;
70322 + vty_out (vty, " Static MPLS tunnel out-segment: ");
70323 + if (if_data && if_data->ops && if_data->ops->info)
70325 + struct zmpls_out_segment *out;
70327 + out = mpls_out_segment_find_by_out_key((int)if_data->ops->info);
70328 + if (out)
70330 + mpls_out_segment_config_write (vty, out);
70331 + vty_out (vty, "%s", VTY_NEWLINE);
70333 + else
70335 + vty_out (vty, " (invalid)%s", VTY_NEWLINE);
70338 + else
70340 + vty_out (vty, " (not configured)%s", VTY_NEWLINE);
70344 +DEFUN (mpls_labelspace,
70345 + mpls_labelspace_cmd,
70346 + "mpls labelspace <0-255>",
70347 + "MPLS interface configuration\n"
70348 + "labelspace\n"
70349 + "labelspace number\n")
70351 + struct interface *ifp;
70352 + int labelspace = atoi(argv[0]);
70354 + ifp = vty->index;
70355 + vty_out(vty, "Labelspace: %d%s",labelspace, VTY_NEWLINE);
70356 + if (labelspace < 0) {
70357 + vty_out(vty, "%% Invalid labelspace '%s'%s",argv[0], VTY_NEWLINE);
70358 + return CMD_WARNING;
70361 + mpls_ctrl_set_interface_labelspace(ifp, labelspace);
70362 + ifp->mpls_labelspace = labelspace;
70363 + redistribute_add_mpls_labelspace (ifp);
70365 + return CMD_SUCCESS;
70368 +DEFUN (no_mpls_labelspace,
70369 + no_mpls_labelspace_cmd,
70370 + "no mpls labelspace",
70371 + NO_STR
70372 + "MPLS interface configuration\n"
70373 + "labelspace\n")
70375 + struct interface *ifp;
70376 + ifp = vty->index;
70378 + mpls_ctrl_set_interface_labelspace(ifp, -1);
70379 + redistribute_delete_mpls_labelspace (ifp);
70380 + ifp->mpls_labelspace = -1;
70382 + return CMD_SUCCESS;
70385 +void mpls_print_label(struct zmpls_label *label, char *buf)
70387 + switch (label->type)
70389 + case ZEBRA_MPLS_LABEL_GEN:
70390 + sprintf(buf, "%u", label->u.gen);
70391 + break;
70392 + case ZEBRA_MPLS_LABEL_ATM:
70393 + sprintf(buf, "%hu/%hu", label->u.atm.vpi, label->u.atm.vci);
70394 + break;
70395 + case ZEBRA_MPLS_LABEL_FR:
70396 + sprintf(buf, "%u", label->u.fr);
70397 + break;
70401 +DEFUN (mpls_show_mpls_fwd,
70402 + mpls_show_mpls_fwd_cmd,
70403 + "show mpls forwarding",
70404 + SHOW_STR
70405 + "MPLS commands\n"
70406 + "forwarding table\n")
70408 + struct zmpls_out_segment *out;
70409 + struct zmpls_in_segment *in;
70410 + struct zmpls_xc *xc;
70411 + struct listnode *node;
70412 + int count;
70414 + vty_out(vty, "Insegments:%s",VTY_NEWLINE);
70416 + count = 0;
70417 + for (ALL_LIST_ELEMENTS_RO(&mpls_in_segment_list, node, in))
70419 + char buf[16];
70421 + mpls_print_label(&in->label, buf);
70423 + if (!count) {
70424 + vty_out(vty, " Lbl Spc Label Owner%s", VTY_NEWLINE);
70426 + vty_out(vty, " %-3d %7s %-6s", in->labelspace,
70427 + buf, zebra_route_string(in->owner));
70429 + if (!in->installed)
70430 + vty_out(vty, " (inactive)");
70432 + vty_out(vty, "%s", VTY_NEWLINE);
70433 + count++;
70435 + if (!count) {
70436 + vty_out(vty, "%s", VTY_NEWLINE);
70438 + vty_out(vty, "Total %d%s",count, VTY_NEWLINE);
70439 + vty_out(vty, "%s", VTY_NEWLINE);
70441 + vty_out(vty, "Outsegments:%s",VTY_NEWLINE);
70442 + count = 0;
70443 + for (ALL_LIST_ELEMENTS_RO(&mpls_out_segment_list, node, out))
70445 + char buf2[16];
70446 + char buf[48];
70447 + char *ifname = NULL;
70449 + if (!count) {
70450 + vty_out (vty, " Interface Label Next Hop Owner%s",
70451 + VTY_NEWLINE);
70454 + if (CHECK_FLAG (out->nh.type, ZEBRA_NEXTHOP_IFNAME))
70456 + ifname = out->nh.intf.name;
70457 + } else {
70458 + ifname = "(remote)";
70461 + if (CHECK_FLAG (out->nh.type, ZEBRA_NEXTHOP_IPV4))
70463 + inet_ntop (AF_INET, &out->nh.gw.ipv4, buf, sizeof(buf));
70464 + } else if (CHECK_FLAG (out->nh.type, ZEBRA_NEXTHOP_IPV6)) {
70465 + inet_ntop (AF_INET6, &out->nh.gw.ipv6, buf, sizeof(buf));
70466 + } else {
70467 + strcpy (buf, "0.0.0.0");
70470 + mpls_print_label(&out->nh.mpls, buf2);
70472 + vty_out(vty, " %-16s %7s %-15s %-6s", ifname,
70473 + buf2, buf, zebra_route_string(out->owner));
70475 + if (!out->installed)
70476 + vty_out(vty, " (inactive)");
70478 + vty_out(vty, "%s", VTY_NEWLINE);
70479 + count++;
70481 + if (!count) {
70482 + vty_out(vty, "%s", VTY_NEWLINE);
70484 + vty_out(vty, "Total %d%s",count, VTY_NEWLINE);
70485 + vty_out(vty, "%s", VTY_NEWLINE);
70487 + vty_out(vty, "Cross Connects:%s",VTY_NEWLINE);
70488 + count = 0;
70489 + for (ALL_LIST_ELEMENTS_RO(&mpls_xc_list, node, xc))
70491 + char buf[48];
70492 + char buf2[48];
70493 + char buf3[48];
70494 + char *ifname = NULL;
70495 + struct zmpls_in_segment tmp;
70496 + struct zmpls_in_segment *in;
70497 + struct zmpls_out_segment *out;
70499 + out = mpls_out_segment_find(xc->out_index);
70501 + tmp.labelspace = xc->in_labelspace;
70502 + memcpy(&tmp.label, &xc->in_label, sizeof(struct zmpls_label));
70503 + in = mpls_in_segment_find(&tmp);
70505 + if (!count) {
70506 + vty_out(vty, " Lbl Spc In Label Out Label Interface "
70507 + "Next Hop Owner%s", VTY_NEWLINE);
70510 + mpls_print_label(&in->label, buf);
70511 + mpls_print_label(&out->nh.mpls, buf2);
70513 + if (CHECK_FLAG (out->nh.type, ZEBRA_NEXTHOP_IFNAME))
70515 + ifname = out->nh.intf.name;
70516 + } else {
70517 + ifname = "(remote)";
70520 + if (CHECK_FLAG (out->nh.type, ZEBRA_NEXTHOP_IPV4))
70522 + inet_ntop (AF_INET, &out->nh.gw.ipv6, buf3, sizeof(buf3));
70523 + } else if (CHECK_FLAG (out->nh.type, ZEBRA_NEXTHOP_IPV6)) {
70524 + inet_ntop (AF_INET6, &out->nh.gw.ipv6, buf3, sizeof(buf3));
70525 + } else {
70526 + strcpy (buf3, "0.0.0.0");
70529 + vty_out(vty, " %-3d %7s %7s %-16s %-15s %-6s",
70530 + xc->in_labelspace, buf, buf2, ifname, buf3,
70531 + zebra_route_string(in->owner));
70533 + if (!xc->installed)
70534 + vty_out(vty, " (inactive)");
70536 + vty_out(vty, "%s", VTY_NEWLINE);
70537 + count++;
70539 + if (!count) {
70540 + vty_out(vty, "%s", VTY_NEWLINE);
70542 + vty_out(vty, "Total %d%s",count, VTY_NEWLINE);
70543 + vty_out(vty, "%s", VTY_NEWLINE);
70545 + return CMD_SUCCESS;
70548 +#ifdef LINUX_MPLS
70549 +DEFUN (mpls_show_mpls_version,
70550 + mpls_show_mpls_version_cmd,
70551 + "show mpls version",
70552 + SHOW_STR
70553 + "MPLS 'show' commands\n"
70554 + "Show MPLS version\n")
70556 + vty_out(vty, "Version %d.%d%d%d%s", (MPLS_LINUX_VERSION >> 24) & 0xFF,
70557 + (MPLS_LINUX_VERSION >> 16) & 0xFF, (MPLS_LINUX_VERSION >> 8) & 0xFF,
70558 + (MPLS_LINUX_VERSION) & 0xFF, VTY_NEWLINE);
70559 + return CMD_SUCCESS;
70561 +#endif
70563 +DEFUN (mpls_show_mpls_hardware,
70564 + mpls_show_mpls_hardware_cmd,
70565 + "show mpls hardware",
70566 + SHOW_STR
70567 + "MPLS 'show' commands\n"
70568 + "Show MPLS forwarder type\n")
70570 + return mpls_ctrl_show_hardware(vty);
70573 +static void
70574 +mpls_label_config_write (struct vty *vty, struct zmpls_label *label)
70576 + switch (label->type)
70578 + case ZEBRA_MPLS_LABEL_GEN:
70579 + vty_out (vty, "gen %d", label->u.gen);
70580 + break;
70581 + case ZEBRA_MPLS_LABEL_ATM:
70582 + vty_out (vty, "atm %d/%d", label->u.atm.vpi, label->u.atm.vci);
70583 + break;
70584 + case ZEBRA_MPLS_LABEL_FR:
70585 + vty_out (vty, "fr %d", label->u.fr);
70586 + break;
70590 +void
70591 +mpls_out_segment_config_write (struct vty *vty, struct zmpls_out_segment *out)
70593 + char buf[128] = "";
70595 + mpls_label_config_write (vty, &out->nh.mpls);
70596 + vty_out (vty, " nexthop");
70598 + if (CHECK_FLAG (out->nh.type, ZEBRA_NEXTHOP_IFNAME))
70600 + vty_out (vty, " %s", out->nh.intf.name);
70603 + if (CHECK_FLAG (out->nh.type, ZEBRA_NEXTHOP_IPV6))
70605 + inet_ntop (AF_INET6, &out->nh.gw.ipv6, buf, sizeof (buf));
70607 + else if (CHECK_FLAG (out->nh.type, ZEBRA_NEXTHOP_IPV4))
70609 + inet_ntop (AF_INET, &out->nh.gw.ipv4, buf, sizeof (buf));
70611 + vty_out (vty, " %s", buf);
70614 +static void
70615 +mpls_in_segment_config_write (struct vty *vty, struct zmpls_in_segment *in)
70617 + mpls_label_config_write (vty, &in->label);
70619 + if (in->xc)
70621 + struct zmpls_out_segment *out;
70622 + struct zmpls_xc *xc;
70624 + vty_out (vty, " swap ");
70625 + xc = mpls_xc_find (in->xc);
70626 + out = mpls_out_segment_find (xc->out_index);
70627 + if (out)
70629 + mpls_out_segment_config_write (vty, out);
70631 + else
70633 + vty_out (vty, "(unable to find out-segment with index %d)", in->xc);
70635 + } else if (in->pop) {
70636 + vty_out (vty, " pop");
70637 + } else {
70638 + vty_out (vty, "(invalid ILM)");
70642 +static int
70643 +mpls_static_config_write (struct vty *vty)
70645 + struct listnode *node;
70646 + struct zmpls_in_segment *in;
70647 + int labelspace;
70648 + int first;
70650 + for (labelspace = 0;labelspace < 256;labelspace++)
70652 + first = 1;
70654 + for (ALL_LIST_ELEMENTS_RO (&mpls_in_segment_list, node, in))
70656 + if (in->owner != ZEBRA_ROUTE_STATIC &&
70657 + in->owner != ZEBRA_ROUTE_KERNEL )
70658 + continue;
70660 + if (in->labelspace != labelspace)
70661 + continue;
70663 + if (first)
70664 + vty_out (vty, "mpls static %d%s", labelspace, VTY_NEWLINE);
70666 + vty_out (vty, " label-map ");
70667 + mpls_in_segment_config_write (vty, in);
70668 + vty_out (vty, "%s", VTY_NEWLINE);
70669 + first = 0;
70671 + vty_out (vty, "!%s", VTY_NEWLINE);
70673 + return 0;
70676 +static
70677 +struct cmd_node mpls_static_node =
70679 + MPLS_LABELSPACE_NODE,
70680 + "%s(config-ls)# ",
70684 +void
70685 +mpls_vty_init ()
70687 + install_element (CONFIG_NODE, &mpls_static_num_cmd);
70688 + install_element (CONFIG_NODE, &no_mpls_static_num_cmd);
70689 + install_element (INTERFACE_NODE, &mpls_labelspace_cmd);
70690 + install_element (INTERFACE_NODE, &no_mpls_labelspace_cmd);
70692 + install_node (&mpls_static_node, mpls_static_config_write);
70693 + install_default (MPLS_LABELSPACE_NODE);
70695 + install_element (MPLS_LABELSPACE_NODE, &label_map_pop_cmd);
70696 + install_element (MPLS_LABELSPACE_NODE, &label_map_swap_if_cmd);
70697 + install_element (MPLS_LABELSPACE_NODE, &label_map_swap_if_addr_cmd);
70698 + install_element (MPLS_LABELSPACE_NODE, &no_label_map_cmd);
70700 + install_element (VIEW_NODE, &mpls_show_mpls_fwd_cmd);
70701 + install_element (ENABLE_NODE, &mpls_show_mpls_fwd_cmd);
70702 +#ifdef LINUX_MPLS
70703 + install_element (VIEW_NODE, &mpls_show_mpls_version_cmd);
70704 + install_element (ENABLE_NODE, &mpls_show_mpls_version_cmd);
70705 +#endif
70706 + install_element (VIEW_NODE, &mpls_show_mpls_hardware_cmd);
70707 + install_element (ENABLE_NODE, &mpls_show_mpls_hardware_cmd);
70710 +#endif /* HAVE_MPLS */
70711 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/mpls_vty.h quagga-mpls/zebra/mpls_vty.h
70712 --- quagga/zebra/mpls_vty.h 1969-12-31 18:00:00.000000000 -0600
70713 +++ quagga-mpls/zebra/mpls_vty.h 2006-11-29 22:53:17.000000000 -0600
70714 @@ -0,0 +1,40 @@
70716 + * MPLS CLI for zebra daemon.
70718 + * Copyright (C) 2004 James R. Leu
70720 + * This file is part of Quagga routing suite.
70722 + * Quagga is free software; you can redistribute it and/or modify it
70723 + * under the terms of the GNU General Public License as published by the
70724 + * Free Software Foundation; either version 2, or (at your option) any
70725 + * later version.
70727 + * Quagga is distributed in the hope that it will be useful, but
70728 + * WITHOUT ANY WARRANTY; without even the implied warranty of
70729 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
70730 + * General Public License for more details.
70732 + * You should have received a copy of the GNU General Public License
70733 + * along with GNU Zebra; see the file COPYING. If not, write to the Free
70734 + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
70735 + * 02111-1307, USA.
70736 + */
70738 +#ifndef _ZEBRA_MPLS_VTY_H
70739 +#define _ZEBRA_MPLS_VTY_H
70741 +#include "mpls_lib.h"
70742 +#include "vty.h"
70744 +extern void mpls_vty_init();
70745 +extern void mpls_print_label(struct zmpls_label *label, char *buf);
70747 +extern void
70748 +mpls_out_segment_config_write (struct vty *vty, struct zmpls_out_segment *out);
70750 +extern int
70751 +nhlfe_parse(struct vty *vty, const char **argv, struct zmpls_out_segment *out,
70752 + const char* addr);
70754 +#endif /* _ZEBRA_MPLS_VTY_H */
70755 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/netlink.c quagga-mpls/zebra/netlink.c
70756 --- quagga/zebra/netlink.c 1969-12-31 18:00:00.000000000 -0600
70757 +++ quagga-mpls/zebra/netlink.c 2008-02-19 22:55:40.000000000 -0600
70758 @@ -0,0 +1,623 @@
70759 +/* Kernel routing table updates using netlink over GNU/Linux system.
70760 + * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
70762 + * This file is part of GNU Zebra.
70764 + * GNU Zebra is free software; you can redistribute it and/or modify it
70765 + * under the terms of the GNU General Public License as published by the
70766 + * Free Software Foundation; either version 2, or (at your option) any
70767 + * later version.
70769 + * GNU Zebra is distributed in the hope that it will be useful, but
70770 + * WITHOUT ANY WARRANTY; without even the implied warranty of
70771 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
70772 + * General Public License for more details.
70774 + * You should have received a copy of the GNU General Public License
70775 + * along with GNU Zebra; see the file COPYING. If not, write to the Free
70776 + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
70777 + * 02111-1307, USA.
70778 + */
70780 +#include <zebra.h>
70782 +/* Hack for GNU libc version 2. */
70783 +#ifndef MSG_TRUNC
70784 +#define MSG_TRUNC 0x20
70785 +#endif /* MSG_TRUNC */
70787 +#include "linklist.h"
70788 +#include "if.h"
70789 +#include "log.h"
70790 +#include "prefix.h"
70791 +#include "connected.h"
70792 +#include "table.h"
70793 +#include "rib.h"
70794 +#include "thread.h"
70795 +#include "privs.h"
70797 +#include "zebra/zserv.h"
70798 +#include "zebra/redistribute.h"
70799 +#include "zebra/interface.h"
70800 +#include "zebra/debug.h"
70801 +#include "zebra/netlink.h"
70803 +extern struct zebra_t zebrad;
70804 +extern struct zebra_privs_t zserv_privs;
70805 +extern u_int32_t nl_rcvbufsize;
70807 +struct message nlmsg_str[] = {
70808 + {RTM_NEWROUTE, "RTM_NEWROUTE"},
70809 + {RTM_DELROUTE, "RTM_DELROUTE"},
70810 + {RTM_GETROUTE, "RTM_GETROUTE"},
70811 + {RTM_NEWLINK, "RTM_NEWLINK"},
70812 + {RTM_DELLINK, "RTM_DELLINK"},
70813 + {RTM_GETLINK, "RTM_GETLINK"},
70814 + {RTM_NEWADDR, "RTM_NEWADDR"},
70815 + {RTM_DELADDR, "RTM_DELADDR"},
70816 + {RTM_GETADDR, "RTM_GETADDR"},
70817 + {0, NULL}
70820 +char *nexthop_types_desc(int x)
70822 + static char buf[1024];
70823 + if (CHECK_FLAG (x, ZEBRA_NEXTHOP_IFINDEX)) {
70824 + sprintf(buf, "ifindex ");
70826 + if (CHECK_FLAG (x, ZEBRA_NEXTHOP_IFNAME)) {
70827 + sprintf(buf, "ifname ");
70829 + if (CHECK_FLAG (x, ZEBRA_NEXTHOP_IPV4)) {
70830 + sprintf(buf, "IPv4 ");
70832 + if (CHECK_FLAG (x, ZEBRA_NEXTHOP_IPV6)) {
70833 + sprintf(buf, "IPv6 ");
70835 + if (CHECK_FLAG (x, ZEBRA_NEXTHOP_DROP)) {
70836 + sprintf(buf, "Drop ");
70838 + return buf;
70841 +/* Make socket for Linux netlink interface. */
70842 +int
70843 +netlink_socket (struct nlsock *nl, int proto, unsigned long groups)
70845 + int ret;
70846 + struct sockaddr_nl snl;
70847 + int sock;
70848 + int namelen;
70849 + int save_errno;
70851 + sock = socket (AF_NETLINK, SOCK_RAW, proto);
70852 + if (sock < 0)
70854 + zlog (NULL, LOG_ERR, "Can't open %s socket: %s", nl->name,
70855 + safe_strerror (errno));
70856 + return -1;
70859 + ret = fcntl (sock, F_SETFL, O_NONBLOCK);
70860 + if (ret < 0)
70862 + zlog (NULL, LOG_ERR, "Can't set %s socket flags: %s", nl->name,
70863 + safe_strerror (errno));
70864 + close (sock);
70865 + return -1;
70868 + /* Set receive buffer size if it's set from command line */
70869 + if (nl_rcvbufsize)
70871 + u_int32_t oldsize, oldlen;
70872 + u_int32_t newsize, newlen;
70874 + oldlen = sizeof(oldsize);
70875 + newlen = sizeof(newsize);
70877 + ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldlen);
70878 + if (ret < 0)
70880 + zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name,
70881 + safe_strerror (errno));
70882 + close (sock);
70883 + return -1;
70886 + ret = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &nl_rcvbufsize,
70887 + sizeof(nl_rcvbufsize));
70888 + if (ret < 0)
70890 + zlog (NULL, LOG_ERR, "Can't set %s receive buffer size: %s", nl->name,
70891 + safe_strerror (errno));
70892 + close (sock);
70893 + return -1;
70896 + ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen);
70897 + if (ret < 0)
70899 + zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name,
70900 + safe_strerror (errno));
70901 + close (sock);
70902 + return -1;
70905 + zlog (NULL, LOG_INFO,
70906 + "Setting netlink socket receive buffer size: %u -> %u",
70907 + oldsize, newsize);
70910 + memset (&snl, 0, sizeof snl);
70911 + snl.nl_family = AF_NETLINK;
70912 + snl.nl_groups = groups;
70914 + /* Bind the socket to the netlink structure for anything. */
70915 + if (zserv_privs.change (ZPRIVS_RAISE))
70917 + zlog (NULL, LOG_ERR, "Can't raise privileges");
70918 + return -1;
70921 + ret = bind (sock, (struct sockaddr *) &snl, sizeof snl);
70922 + save_errno = errno;
70923 + if (zserv_privs.change (ZPRIVS_LOWER))
70924 + zlog (NULL, LOG_ERR, "Can't lower privileges");
70926 + if (ret < 0)
70928 + zlog (NULL, LOG_ERR, "Can't bind %s socket to group 0x%x: %s",
70929 + nl->name, snl.nl_groups, safe_strerror (save_errno));
70930 + close (sock);
70931 + return -1;
70934 + /* multiple netlink sockets will have different nl_pid */
70935 + namelen = sizeof snl;
70936 + ret = getsockname (sock, (struct sockaddr *) &snl, (socklen_t *) &namelen);
70937 + if (ret < 0 || namelen != sizeof snl)
70939 + zlog (NULL, LOG_ERR, "Can't get %s socket name: %s", nl->name,
70940 + safe_strerror (errno));
70941 + close (sock);
70942 + return -1;
70945 + nl->snl = snl;
70946 + nl->sock = sock;
70947 + return ret;
70950 +int
70951 +set_netlink_blocking (struct nlsock *nl, int *flags)
70954 + /* Change socket flags for blocking I/O. */
70955 + if ((*flags = fcntl (nl->sock, F_GETFL, 0)) < 0)
70957 + zlog (NULL, LOG_ERR, "%s:%i F_GETFL error: %s",
70958 + __FUNCTION__, __LINE__, safe_strerror (errno));
70959 + return -1;
70961 + *flags &= ~O_NONBLOCK;
70962 + if (fcntl (nl->sock, F_SETFL, *flags) < 0)
70964 + zlog (NULL, LOG_ERR, "%s:%i F_SETFL error: %s",
70965 + __FUNCTION__, __LINE__, safe_strerror (errno));
70966 + return -1;
70968 + return 0;
70971 +int
70972 +set_netlink_nonblocking (struct nlsock *nl, int *flags)
70974 + /* Restore socket flags for nonblocking I/O */
70975 + *flags |= O_NONBLOCK;
70976 + if (fcntl (nl->sock, F_SETFL, *flags) < 0)
70978 + zlog (NULL, LOG_ERR, "%s:%i F_SETFL error: %s",
70979 + __FUNCTION__, __LINE__, safe_strerror (errno));
70980 + return -1;
70982 + return 0;
70985 +static int
70986 +do_netlink_request (struct nlsock *nl, void *buf, int size)
70988 + int ret;
70989 + struct sockaddr_nl snl;
70990 + int save_errno;
70992 + memset (&snl, 0, sizeof snl);
70993 + snl.nl_family = AF_NETLINK;
70995 + /* Check netlink socket. */
70996 + if (nl->sock < 0)
70998 + zlog (NULL, LOG_ERR, "%s socket isn't active.", nl->name);
70999 + return -1;
71002 + /* linux appears to check capabilities on every message
71003 + * have to raise caps for every message sent
71004 + */
71005 + if (zserv_privs.change (ZPRIVS_RAISE))
71007 + zlog (NULL, LOG_ERR, "Can't raise privileges");
71008 + return -1;
71011 + ret = sendto (nl->sock, buf, size, 0, (struct sockaddr *) &snl, sizeof snl);
71012 + save_errno = errno;
71014 + if (zserv_privs.change (ZPRIVS_LOWER))
71015 + zlog (NULL, LOG_ERR, "Can't lower privileges");
71017 + if (ret < 0)
71019 + zlog (NULL, LOG_ERR, "%s sendto failed: %s", nl->name,
71020 + safe_strerror (save_errno));
71021 + return -1;
71024 + return 0;
71027 +/* Get type specified information from netlink. */
71028 +int
71029 +netlink_request (int family, int type, struct nlsock *nl)
71031 + struct
71033 + struct nlmsghdr nlh;
71034 + struct rtgenmsg g;
71035 + } req;
71037 + memset (&req, 0, sizeof req);
71038 + req.nlh.nlmsg_len = sizeof req;
71039 + req.nlh.nlmsg_type = type;
71040 + req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
71041 + req.nlh.nlmsg_pid = 0;
71042 + req.nlh.nlmsg_seq = ++nl->seq;
71043 + req.g.rtgen_family = family;
71045 + return do_netlink_request(nl, (void*)&req, sizeof(req));
71048 +#if defined(HAVE_MPLS) && defined(LINUX_MPLS)
71049 +int
71050 +genetlink_request (int family, int type, struct nlsock *nl)
71052 + struct genlmsghdr *ghdr;
71054 + struct {
71055 + struct nlmsghdr n;
71056 + char buf[4096];
71057 + } req;
71059 + memset(&req, 0, sizeof(req));
71061 + req.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
71062 + req.n.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
71063 + req.n.nlmsg_type = family;
71064 + req.n.nlmsg_seq = ++nl->seq;
71066 + ghdr = NLMSG_DATA(&req.n);
71067 + ghdr->cmd = type;
71069 + return do_netlink_request(nl, (void*)&req, sizeof(req));
71071 +#endif
71073 +/* Receive message from netlink interface and pass those information
71074 + to the given function. */
71075 +int
71076 +netlink_parse_info (int (*filter) (struct nlsock *nl, struct sockaddr_nl *, struct nlmsghdr *),
71077 + struct nlsock *nl, void *a, unsigned int size)
71079 + char buf[16384];
71080 + int status;
71081 + int ret = 0;
71082 + int error;
71084 + if (!a)
71086 + a = (void*)buf;
71087 + size = sizeof(buf);
71090 + while (1)
71092 + struct iovec iov = { a, size };
71093 + struct sockaddr_nl snl;
71094 + struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
71095 + struct nlmsghdr *h;
71096 + int save_errno;
71098 + if (zserv_privs.change (ZPRIVS_RAISE))
71099 + zlog (NULL, LOG_ERR, "Can't raise privileges");
71101 + status = recvmsg (nl->sock, &msg, 0);
71102 + save_errno = errno;
71104 + if (zserv_privs.change (ZPRIVS_LOWER))
71105 + zlog (NULL, LOG_ERR, "Can't lower privileges");
71107 + if (status < 0)
71109 + if (save_errno == EINTR)
71110 + continue;
71111 + if (save_errno == EWOULDBLOCK || save_errno == EAGAIN)
71112 + break;
71113 + zlog (NULL, LOG_ERR, "%s recvmsg overrun: %s",
71114 + nl->name, safe_strerror(save_errno));
71115 + continue;
71118 + if (status == 0)
71120 + zlog (NULL, LOG_ERR, "%s EOF", nl->name);
71121 + return -1;
71124 + if (msg.msg_namelen != sizeof snl)
71126 + zlog (NULL, LOG_ERR, "%s sender address length error: length %d",
71127 + nl->name, msg.msg_namelen);
71128 + return -1;
71131 + /* JF: Ignore messages that aren't from the kernel */
71132 + if ( snl.nl_pid != 0 )
71134 + zlog ( NULL, LOG_ERR, "Ignoring message from pid %u", snl.nl_pid );
71135 + continue;
71138 + for (h = (struct nlmsghdr *) a; NLMSG_OK (h, (unsigned int) status);
71139 + h = NLMSG_NEXT (h, status))
71141 + /* Finish of reading. */
71142 + if (h->nlmsg_type == NLMSG_DONE)
71143 + return ret;
71145 + /* Error handling. */
71146 + if (h->nlmsg_type == NLMSG_ERROR)
71148 + struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h);
71150 + /* If the error field is zero, then this is an ACK */
71151 + if (err->error == 0)
71153 + if (IS_ZEBRA_DEBUG_KERNEL)
71155 + zlog_debug ("%s: %s ACK: type=%s(%u), seq=%u, pid=%u",
71156 + __FUNCTION__, nl->name,
71157 + lookup (nlmsg_str, err->msg.nlmsg_type),
71158 + err->msg.nlmsg_type, err->msg.nlmsg_seq,
71159 + err->msg.nlmsg_pid);
71162 + /* return if not a multipart message, otherwise continue */
71163 + if (!(h->nlmsg_flags & NLM_F_MULTI))
71165 + return 0;
71167 + continue;
71170 + if (h->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr)))
71172 + zlog (NULL, LOG_ERR, "%s error: message truncated",
71173 + nl->name);
71174 + return -1;
71177 + /* Deal with Error Noise - MAG */
71179 + int loglvl = LOG_ERR;
71180 + int errnum = err->error;
71181 + int msg_type = err->msg.nlmsg_type;
71183 + /* nl->cmd is defined only for the CMD sockets */
71184 + if (nl->cmd && (-errnum == ENODEV || -errnum == ESRCH))
71185 + loglvl = LOG_DEBUG;
71187 + zlog (NULL, loglvl, "%s error: %s, type=%s(%u), "
71188 + "seq=%u, pid=%u",
71189 + nl->name, safe_strerror (-errnum),
71190 + lookup (nlmsg_str, msg_type),
71191 + msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid);
71193 + /*
71194 + ret = -1;
71195 + continue;
71196 + */
71197 + return -1;
71200 + /* OK we got netlink message. */
71201 + if (IS_ZEBRA_DEBUG_KERNEL)
71202 + zlog_debug ("netlink_parse_info: %s type %s(%u), seq=%u, pid=%u",
71203 + nl->name,
71204 + lookup (nlmsg_str, h->nlmsg_type), h->nlmsg_type,
71205 + h->nlmsg_seq, h->nlmsg_pid);
71207 + error = (*filter) (nl, &snl, h);
71208 + if (error < 0)
71210 + zlog (NULL, LOG_ERR, "%s filter function error", nl->name);
71211 + ret = error;
71215 + /* After error care. */
71216 + if (msg.msg_flags & MSG_TRUNC)
71218 + zlog (NULL, LOG_ERR, "%s error: message truncated", nl->name);
71219 + continue;
71221 + if (status)
71223 + zlog (NULL, LOG_ERR, "%s error: data remnant size %d", nl->name,
71224 + status);
71225 + return -1;
71228 + return ret;
71231 +/* Utility function for parse rtattr. */
71232 +void
71233 +netlink_parse_rtattr (struct rtattr **tb, int max, struct rtattr *rta,
71234 + int len)
71236 + while (RTA_OK (rta, len))
71238 + if (rta->rta_type <= max)
71239 + tb[rta->rta_type] = rta;
71240 + rta = RTA_NEXT (rta, len);
71244 +/* Utility function comes from iproute2.
71245 + Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
71246 +int
71247 +addattr_l (struct nlmsghdr *n, unsigned int maxlen, int type,
71248 + void *data, int alen)
71250 + int len;
71251 + struct rtattr *rta;
71253 + len = RTA_LENGTH (alen);
71255 + if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen)
71256 + return -1;
71258 + rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len));
71259 + rta->rta_type = type;
71260 + rta->rta_len = len;
71261 + memcpy (RTA_DATA (rta), data, alen);
71262 + n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
71264 + return 0;
71267 +int
71268 +rta_addattr_l (struct rtattr *rta, int maxlen, int type, void *data, int alen)
71270 + int len;
71271 + struct rtattr *subrta;
71273 + len = RTA_LENGTH (alen);
71275 + if (RTA_ALIGN (rta->rta_len) + len > maxlen)
71276 + return -1;
71278 + subrta = (struct rtattr *) (((char *) rta) + RTA_ALIGN (rta->rta_len));
71279 + subrta->rta_type = type;
71280 + subrta->rta_len = len;
71281 + memcpy (RTA_DATA (subrta), data, alen);
71282 + rta->rta_len = NLMSG_ALIGN (rta->rta_len) + len;
71284 + return 0;
71287 +/* Utility function comes from iproute2.
71288 + Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
71289 +int
71290 +addattr32 (struct nlmsghdr *n, unsigned int maxlen, int type, int data)
71292 + int len;
71293 + struct rtattr *rta;
71295 + len = RTA_LENGTH (4);
71297 + if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen)
71298 + return -1;
71300 + rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len));
71301 + rta->rta_type = type;
71302 + rta->rta_len = len;
71303 + memcpy (RTA_DATA (rta), &data, 4);
71304 + n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
71306 + return 0;
71309 +int
71310 +netlink_talk_filter (struct nlsock *nl, struct sockaddr_nl *snl, struct nlmsghdr *h)
71312 + zlog_warn ("netlink_talk: ignoring message type 0x%04x", h->nlmsg_type);
71313 + return 0;
71316 +/* sendmsg() to netlink socket then recvmsg(). */
71317 +int
71318 +netlink_talk (struct nlmsghdr *n, struct nlsock *nl, void *a, unsigned int size)
71320 + int status;
71321 + struct sockaddr_nl snl;
71322 + struct iovec iov = { (void *) n, n->nlmsg_len };
71323 + struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
71324 + int flags = 0;
71325 + int snb_ret;
71326 + int save_errno;
71328 + memset (&snl, 0, sizeof snl);
71329 + snl.nl_family = AF_NETLINK;
71331 + n->nlmsg_seq = ++nl->seq;
71333 + /* Request an acknowledgement by setting NLM_F_ACK */
71334 + if (!a)
71335 + n->nlmsg_flags |= NLM_F_ACK;
71337 + if (IS_ZEBRA_DEBUG_KERNEL)
71338 + zlog_debug ("netlink_talk: %s type %s(%u), seq=%u", nl->name,
71339 + lookup (nlmsg_str, n->nlmsg_type), n->nlmsg_type,
71340 + n->nlmsg_seq);
71342 + /* Send message to netlink interface. */
71343 + if (zserv_privs.change (ZPRIVS_RAISE))
71344 + zlog (NULL, LOG_ERR, "Can't raise privileges");
71345 + status = sendmsg (nl->sock, &msg, 0);
71346 + save_errno = errno;
71347 + if (zserv_privs.change (ZPRIVS_LOWER))
71348 + zlog (NULL, LOG_ERR, "Can't lower privileges");
71350 + if (status < 0)
71352 + zlog (NULL, LOG_ERR, "netlink_talk sendmsg() error: %s",
71353 + safe_strerror (save_errno));
71354 + return -1;
71357 + if (!a)
71359 + /*
71360 + * Change socket flags for blocking I/O.
71361 + * This ensures we wait for a reply in netlink_parse_info().
71362 + */
71363 + snb_ret = set_netlink_blocking (nl, &flags);
71364 + if (snb_ret < 0)
71365 + zlog (NULL, LOG_WARNING,
71366 + "%s:%i Warning: Could not set netlink socket to blocking.",
71367 + __FUNCTION__, __LINE__);
71370 + /*
71371 + * Get reply from netlink socket.
71372 + * The reply should either be an acknowlegement or an error.
71373 + */
71374 + status = netlink_parse_info (netlink_talk_filter, nl, a, size);
71376 + /* Restore socket flags for nonblocking I/O */
71377 + if (snb_ret == 0 && !a)
71378 + set_netlink_nonblocking (nl, &flags);
71380 + return status;
71382 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/netlink.h quagga-mpls/zebra/netlink.h
71383 --- quagga/zebra/netlink.h 1969-12-31 18:00:00.000000000 -0600
71384 +++ quagga-mpls/zebra/netlink.h 2006-11-20 22:47:35.000000000 -0600
71385 @@ -0,0 +1,41 @@
71386 +#ifndef ZEBRA_NETLINK_H
71387 +#define ZEBRA_NETLINK_H
71389 +struct nlsock
71391 + int sock;
71392 + int seq;
71393 + struct sockaddr_nl snl;
71394 + const char *name;
71395 + int cmd;
71398 +extern struct zebra_t zebrad;
71399 +extern struct zebra_privs_t zserv_privs;
71400 +extern u_int32_t nl_rcvbufsize;
71401 +extern struct thread_master *master;
71403 +extern struct message nlmsg_str[];
71405 +extern int genetlink_request (int family, int type, struct nlsock *nl);
71406 +extern int netlink_socket (struct nlsock *nl, int proto, unsigned long groups);
71407 +extern int netlink_request (int family, int type, struct nlsock *nl);
71408 +extern int set_netlink_blocking (struct nlsock *nl, int *flags);
71409 +extern int set_netlink_nonblocking (struct nlsock *nl, int *flags);
71410 +extern int netlink_parse_info (int (*filter) (struct nlsock *nl, struct sockaddr_nl *,
71411 + struct nlmsghdr *), struct nlsock *nl,
71412 + void *a, unsigned int size);
71413 +extern void netlink_parse_rtattr (struct rtattr **tb, int max,
71414 + struct rtattr *rta, int len);
71415 +extern int addattr32 (struct nlmsghdr *n, unsigned int maxlen, int type,
71416 + int data);
71417 +extern int addattr_l (struct nlmsghdr *n, unsigned int maxlen, int type,
71418 + void *data, int alen);
71419 +extern int rta_addattr_l (struct rtattr *rta, int maxlen, int type,
71420 + void *data, int alen);
71421 +extern int netlink_talk_filter (struct nlsock *nl, struct sockaddr_nl *snl, struct nlmsghdr *h);
71422 +extern int netlink_talk (struct nlmsghdr *n, struct nlsock *nl,
71423 + void *a, unsigned int size);
71424 +extern char *nexthop_types_desc(int x);
71426 +#endif
71427 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/redistribute.c quagga-mpls/zebra/redistribute.c
71428 --- quagga/zebra/redistribute.c 2007-04-10 14:21:47.000000000 -0500
71429 +++ quagga-mpls/zebra/redistribute.c 2008-02-19 22:55:40.000000000 -0600
71430 @@ -166,6 +166,38 @@
71431 && zebra_check_addr (&rn->p))
71432 zsend_route_multipath (ZEBRA_IPV6_ROUTE_ADD, client, &rn->p, newrib);
71433 #endif /* HAVE_IPV6 */
71435 +#ifdef HAVE_MPLS
71437 + struct listnode *node;
71438 + struct zmpls_in_segment *in;
71439 + struct zmpls_out_segment *out;
71440 + struct zmpls_ftn *ftn;
71441 + struct zmpls_xc *xc;
71442 + struct interface *ifp;
71444 + for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp))
71445 + if (type == ZEBRA_ROUTE_STATIC &&
71446 + ifp->mpls_labelspace > -1)
71447 + zsend_mpls_labelspace_add (client, ifp);
71449 + for (ALL_LIST_ELEMENTS_RO(&mpls_in_segment_list, node, in))
71450 + if (type == in->owner)
71451 + zsend_mpls_in_segment_add (client, in);
71453 + for (ALL_LIST_ELEMENTS_RO(&mpls_out_segment_list, node, out))
71454 + if (type == out->owner)
71455 + zsend_mpls_out_segment_add (client, out);
71457 + for (ALL_LIST_ELEMENTS_RO(&mpls_xc_list, node, xc))
71458 + if (type == xc->owner)
71459 + zsend_mpls_xc_add (client, xc);
71461 + for (ALL_LIST_ELEMENTS_RO(&mpls_ftn_list, node, ftn))
71462 + if (type == ftn->owner)
71463 + zsend_mpls_ftn_add (client, ftn);
71465 +#endif /* HAVE_MPLS */
71468 void
71469 @@ -174,6 +206,8 @@
71470 struct listnode *node, *nnode;
71471 struct zserv *client;
71473 + /* MPLS: check is there are any FTN waiting for this */
71475 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
71477 if (is_default (p))
71478 @@ -210,6 +244,8 @@
71479 if (rib->distance == DISTANCE_INFINITY)
71480 return;
71482 + /* MPLS: check is there are any FTN depending on this */
71484 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
71486 if (is_default (p))
71487 @@ -255,6 +291,7 @@
71488 case ZEBRA_ROUTE_OSPF:
71489 case ZEBRA_ROUTE_OSPF6:
71490 case ZEBRA_ROUTE_BGP:
71491 + case ZEBRA_ROUTE_LDP:
71492 if (! client->redist[type])
71494 client->redist[type] = 1;
71495 @@ -283,6 +320,7 @@
71496 case ZEBRA_ROUTE_OSPF:
71497 case ZEBRA_ROUTE_OSPF6:
71498 case ZEBRA_ROUTE_BGP:
71499 + case ZEBRA_ROUTE_LDP:
71500 client->redist[type] = 0;
71501 break;
71502 default:
71503 @@ -316,6 +354,29 @@
71505 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
71506 zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
71508 +#ifdef HAVE_MPLS
71509 + if (ifp->mpls_labelspace >= 0)
71510 + mpls_ctrl_set_interface_labelspace(ifp, ifp->mpls_labelspace);
71512 + /* MPLS: check if there are any NHLFE waiting for this */
71513 + if (if_is_operative(ifp))
71515 + struct zmpls_out_segment *out;
71516 + for (ALL_LIST_ELEMENTS_RO(&mpls_out_segment_list, node, out))
71518 + if ((out->installed) ||
71519 + !mpls_nexthop_ready(&out->nh))
71520 + continue;
71522 + out->installed = 1;
71523 + mpls_ctrl_nhlfe_register(out);
71524 + redistribute_add_mpls_out_segment (out);
71526 + } else {
71527 + assert(0);
71529 +#endif /* HAVE_MPLS */
71532 /* Interface down information. */
71533 @@ -328,6 +389,21 @@
71534 if (IS_ZEBRA_DEBUG_EVENT)
71535 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);
71537 +#ifdef HAVE_MPLS
71538 + /* MPLS: check if there are any NHLFE depending on this */
71539 + struct zmpls_out_segment *out;
71540 + for (ALL_LIST_ELEMENTS_RO(&mpls_out_segment_list, node, out))
71542 + if ((!out->installed) ||
71543 + mpls_nexthop_ready(&out->nh))
71544 + continue;
71546 + redistribute_delete_mpls_out_segment (out);
71547 + mpls_ctrl_nhlfe_unregister(out);
71548 + out->installed = 0;
71550 +#endif /* HAVE_MPLS */
71552 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
71553 zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
71555 @@ -345,6 +421,24 @@
71556 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
71557 if (client->ifinfo)
71558 zsend_interface_add (client, ifp);
71560 +#ifdef HAVE_MPLS
71561 + /* MPLS: check if there are any NHLFE waiting for this */
71562 + if (if_is_operative(ifp))
71564 + struct zmpls_out_segment *out;
71565 + for (ALL_LIST_ELEMENTS_RO(&mpls_out_segment_list, node, out))
71567 + if ((out->installed) ||
71568 + !mpls_nexthop_ready(&out->nh))
71569 + continue;
71571 + out->installed = 1;
71572 + mpls_ctrl_nhlfe_register(out);
71573 + redistribute_add_mpls_out_segment (out);
71576 +#endif /* HAVE_MPLS */
71579 void
71580 @@ -356,6 +450,21 @@
71581 if (IS_ZEBRA_DEBUG_EVENT)
71582 zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);
71584 +#ifdef HAVE_MPLS
71585 + /* MPLS: check if there are any NHLFE depending on this */
71586 + struct zmpls_out_segment *out;
71587 + for (ALL_LIST_ELEMENTS_RO(&mpls_out_segment_list, node, out))
71589 + if ((!out->installed) ||
71590 + mpls_nexthop_ready(&out->nh))
71591 + continue;
71593 + out->installed = 0;
71594 + redistribute_delete_mpls_out_segment (out);
71595 + mpls_ctrl_nhlfe_unregister(out);
71597 +#endif /* HAVE_MPLS */
71599 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
71600 if (client->ifinfo)
71601 zsend_interface_delete (client, ifp);
71602 @@ -379,11 +488,29 @@
71603 p->prefixlen, ifc->ifp->name);
71606 - router_id_add_address(ifc);
71608 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
71609 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
71610 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc);
71612 + router_id_add_address(ifc);
71614 +#ifdef HAVE_MPLS
71615 + /* MPLS: check if there are any NHLFE waiting for this */
71616 + if (if_is_operative(ifp))
71618 + struct zmpls_out_segment *out;
71619 + for (ALL_LIST_ELEMENTS_RO(&mpls_out_segment_list, node, out))
71621 + if ((out->installed) ||
71622 + !mpls_nexthop_ready(&out->nh))
71623 + continue;
71625 + out->installed = 1;
71626 + mpls_ctrl_nhlfe_register(out);
71627 + redistribute_add_mpls_out_segment (out);
71630 +#endif /* HAVE_MPLS */
71633 /* Interface address deletion. */
71634 @@ -404,9 +531,240 @@
71635 p->prefixlen, ifc->ifp->name);
71638 +#ifdef HAVE_MPLS
71639 + /* MPLS: check if there are any NHLFE depending on this */
71640 + struct zmpls_out_segment *out;
71641 + for (ALL_LIST_ELEMENTS_RO(&mpls_out_segment_list, node, out))
71643 + if ((!out->installed) ||
71644 + mpls_nexthop_ready(&out->nh))
71645 + continue;
71647 + redistribute_delete_mpls_out_segment (out);
71648 + mpls_ctrl_nhlfe_unregister(out);
71649 + out->installed = 0;
71651 +#endif /* HAVE_MPLS */
71653 router_id_del_address(ifc);
71655 for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
71656 if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
71657 zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc);
71660 +#ifdef HAVE_MPLS
71661 +void
71662 +redistribute_add_mpls_xc (struct zmpls_xc *xc)
71664 + struct listnode *node;
71665 + struct zserv *client;
71667 + /* Check to see and and ILM are waiting for this xc */
71668 + struct zmpls_in_segment *in;
71669 + for (ALL_LIST_ELEMENTS_RO(&mpls_in_segment_list, node, in))
71671 + if (in->installed || in->xc != xc->index)
71672 + continue;
71674 + in->installed = 1;
71675 + mpls_ctrl_ilm_register (in);
71676 + redistribute_add_mpls_in_segment (in);
71679 + for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
71680 + if (client->redist[xc->owner])
71681 + zsend_mpls_xc_add (client, xc);
71684 +void
71685 +redistribute_delete_mpls_xc (struct zmpls_xc *xc)
71687 + struct listnode *node;
71688 + struct zserv *client;
71690 + for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
71691 + if (client->redist[xc->owner])
71692 + zsend_mpls_xc_delete (client, xc);
71694 + /* Check to see and and ILM depend on this xc */
71695 + struct zmpls_in_segment *in;
71696 + for (ALL_LIST_ELEMENTS_RO(&mpls_in_segment_list, node, in))
71698 + if ((!in->installed) || in->xc != xc->index)
71699 + continue;
71701 + in->installed = 0;
71702 + mpls_ctrl_ilm_unregister (in);
71703 + redistribute_delete_mpls_in_segment (in);
71707 +void
71708 +redistribute_add_mpls_in_segment (struct zmpls_in_segment *in)
71710 + struct listnode *node;
71711 + struct zserv *client;
71713 + /* MPLS: check is there are any XC waiting for this */
71714 + struct zmpls_xc *xc;
71715 + for (ALL_LIST_ELEMENTS_RO(&mpls_xc_list, node, xc))
71717 + struct zmpls_out_segment *out;
71718 + struct zmpls_in_segment tmp;
71720 + tmp.labelspace = xc->in_labelspace;
71721 + memcpy(&tmp.label, &xc->in_label, sizeof(struct zmpls_label));
71723 + if (xc->installed || !mpls_in_segment_match(in, &tmp))
71724 + continue;
71726 + out = mpls_out_segment_find (xc->out_index);
71728 + xc->installed = 1;
71729 + mpls_ctrl_xc_register (in, out);
71730 + redistribute_add_mpls_xc (xc);
71733 + for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
71734 + if (client->redist[in->owner])
71735 + zsend_mpls_in_segment_add (client, in);
71738 +void
71739 +redistribute_delete_mpls_in_segment (struct zmpls_in_segment *in)
71741 + struct listnode *node;
71742 + struct zserv *client;
71744 + for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
71745 + if (client->redist[in->owner])
71746 + zsend_mpls_in_segment_delete (client, in);
71748 + /* MPLS: check is there are any XC depending on this */
71749 + struct zmpls_xc *xc;
71750 + for (ALL_LIST_ELEMENTS_RO(&mpls_xc_list, node, xc))
71752 + struct zmpls_out_segment *out;
71753 + struct zmpls_in_segment tmp;
71755 + tmp.labelspace = xc->in_labelspace;
71756 + memcpy(&tmp.label, &xc->in_label, sizeof(struct zmpls_label));
71758 + if ((!xc->installed) || !mpls_in_segment_match(in, &tmp))
71759 + continue;
71761 + out = mpls_out_segment_find (xc->out_index);
71763 + xc->installed = 0;
71764 + mpls_ctrl_xc_unregister (in, out);
71765 + redistribute_delete_mpls_xc (xc);
71769 +void
71770 +redistribute_add_mpls_out_segment (struct zmpls_out_segment *out)
71772 + struct listnode *node;
71773 + struct zserv *client;
71775 + /* MPLS: check is there are any FTN waiting for this */
71776 + /* MPLS: check is there are any XC waiting for this */
71777 + struct zmpls_xc *xc;
71778 + for (ALL_LIST_ELEMENTS_RO(&mpls_xc_list, node, xc))
71780 + struct zmpls_in_segment tmp;
71781 + struct zmpls_in_segment *in;
71783 + if (xc->installed || xc->out_index != out->index)
71784 + continue;
71786 + tmp.labelspace = xc->in_labelspace;
71787 + memcpy(&tmp.label, &xc->in_label, sizeof(struct zmpls_label));
71788 + in = mpls_in_segment_find (&tmp);
71790 + xc->installed = 1;
71791 + redistribute_add_mpls_xc (xc);
71792 + mpls_ctrl_xc_register (in, out);
71795 + for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
71796 + if (client->redist[out->owner])
71797 + zsend_mpls_out_segment_add (client, out);
71800 +void
71801 +redistribute_delete_mpls_out_segment (struct zmpls_out_segment *out)
71803 + struct listnode *node;
71804 + struct zserv *client;
71806 + for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
71807 + if (client->redist[out->owner])
71808 + zsend_mpls_out_segment_delete (client, out);
71810 + /* MPLS: check is there are any FTN depending on this */
71811 + /* MPLS: check is there are any XC depending on this */
71812 + struct zmpls_xc *xc;
71813 + for (ALL_LIST_ELEMENTS_RO(&mpls_xc_list, node, xc))
71815 + struct zmpls_in_segment tmp;
71816 + struct zmpls_in_segment *in;
71818 + if ((!xc->installed) || xc->out_index != out->index)
71819 + continue;
71821 + tmp.labelspace = xc->in_labelspace;
71822 + memcpy(&tmp.label, &xc->in_label, sizeof(struct zmpls_label));
71823 + in = mpls_in_segment_find (&tmp);
71825 + xc->installed = 0;
71826 + mpls_ctrl_xc_unregister (in, out);
71827 + redistribute_delete_mpls_xc (xc);
71831 +void
71832 +redistribute_add_mpls_labelspace (struct interface *ifp)
71834 + struct listnode *node;
71835 + struct zserv *client;
71837 + for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
71838 + if (client->redist[ZEBRA_ROUTE_STATIC])
71839 + zsend_mpls_labelspace_add (client, ifp);
71842 +void
71843 +redistribute_delete_mpls_labelspace (struct interface *ifp)
71845 + struct listnode *node;
71846 + struct zserv *client;
71848 + for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
71849 + if (client->redist[ZEBRA_ROUTE_STATIC])
71850 + zsend_mpls_labelspace_delete (client, ifp);
71853 +void
71854 +redistribute_add_mpls_ftn (struct zmpls_ftn *ftn)
71856 + struct listnode *node;
71857 + struct zserv *client;
71859 + for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
71860 + if (client->redist[ftn->owner])
71861 + zsend_mpls_ftn_add (client, ftn);
71864 +void
71865 +redistribute_delete_mpls_ftn (struct zmpls_ftn *ftn)
71867 + struct listnode *node;
71868 + struct zserv *client;
71870 + for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client))
71871 + if (client->redist[ftn->owner])
71872 + zsend_mpls_ftn_delete (client, ftn);
71874 +#endif /* HAVE_MPLS */
71875 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/redistribute.h quagga-mpls/zebra/redistribute.h
71876 --- quagga/zebra/redistribute.h 2007-04-10 14:21:47.000000000 -0500
71877 +++ quagga-mpls/zebra/redistribute.h 2008-02-21 23:05:09.000000000 -0600
71878 @@ -47,6 +47,17 @@
71879 struct connected *c);
71881 extern int zebra_check_addr (struct prefix *);
71882 +#ifdef HAVE_MPLS
71883 +void redistribute_add_mpls_xc (struct zmpls_xc *xc);
71884 +void redistribute_delete_mpls_xc (struct zmpls_xc *xc);
71885 +void redistribute_add_mpls_ftn (struct zmpls_ftn *ftn);
71886 +void redistribute_delete_mpls_ftn (struct zmpls_ftn *ftn);
71887 +void redistribute_add_mpls_in_segment (struct zmpls_in_segment *in);
71888 +void redistribute_delete_mpls_in_segment (struct zmpls_in_segment *in);
71889 +void redistribute_add_mpls_out_segment (struct zmpls_out_segment *out);
71890 +void redistribute_delete_mpls_out_segment (struct zmpls_out_segment *out);
71891 +void redistribute_add_mpls_labelspace (struct interface *ifp);
71892 +void redistribute_delete_mpls_labelspace (struct interface *ifp);
71893 +#endif
71895 #endif /* _ZEBRA_REDISTRIBUTE_H */
71897 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/rib.h quagga-mpls/zebra/rib.h
71898 --- quagga/zebra/rib.h 2008-09-04 20:37:37.000000000 -0500
71899 +++ quagga-mpls/zebra/rib.h 2008-09-07 20:23:37.000000000 -0500
71900 @@ -24,9 +24,12 @@
71901 #define _ZEBRA_RIB_H
71903 #include "prefix.h"
71904 +#include "zclient.h"
71906 #define DISTANCE_INFINITY 255
71908 +#include "table.h"
71910 /* Routing information base. */
71912 union g_addr {
71913 @@ -71,7 +74,7 @@
71914 * This flag's definition is in lib/zebra.h ZEBRA_FLAG_* and is exposed
71915 * to clients via Zserv
71917 - u_char flags;
71918 + u_short flags;
71920 /* RIB internal status */
71921 u_char status;
71922 @@ -98,77 +101,15 @@
71925 /* Static route information. */
71926 -struct static_ipv4
71928 - /* For linked list. */
71929 - struct static_ipv4 *prev;
71930 - struct static_ipv4 *next;
71932 - /* Administrative distance. */
71933 - u_char distance;
71935 - /* Flag for this static route's type. */
71936 - u_char type;
71937 -#define STATIC_IPV4_GATEWAY 1
71938 -#define STATIC_IPV4_IFNAME 2
71939 -#define STATIC_IPV4_BLACKHOLE 3
71941 - /* Nexthop value. */
71942 - union
71944 - struct in_addr ipv4;
71945 - char *ifname;
71946 - } gate;
71948 - /* bit flags */
71949 - u_char flags;
71951 - see ZEBRA_FLAG_REJECT
71952 - ZEBRA_FLAG_BLACKHOLE
71953 - */
71956 -#ifdef HAVE_IPV6
71957 -/* Static route information. */
71958 -struct static_ipv6
71959 +struct static_route
71961 /* For linked list. */
71962 - struct static_ipv6 *prev;
71963 - struct static_ipv6 *next;
71964 + struct static_route *prev;
71965 + struct static_route *next;
71967 /* Administrative distance. */
71968 u_char distance;
71970 - /* Flag for this static route's type. */
71971 - u_char type;
71972 -#define STATIC_IPV6_GATEWAY 1
71973 -#define STATIC_IPV6_GATEWAY_IFNAME 2
71974 -#define STATIC_IPV6_IFNAME 3
71976 - /* Nexthop value. */
71977 - struct in6_addr ipv6;
71978 - char *ifname;
71980 - /* bit flags */
71981 - u_char flags;
71983 - see ZEBRA_FLAG_REJECT
71984 - ZEBRA_FLAG_BLACKHOLE
71985 - */
71987 -#endif /* HAVE_IPV6 */
71989 -enum nexthop_types_t
71991 - NEXTHOP_TYPE_IFINDEX = 1, /* Directly connected. */
71992 - NEXTHOP_TYPE_IFNAME, /* Interface route. */
71993 - NEXTHOP_TYPE_IPV4, /* IPv4 nexthop. */
71994 - NEXTHOP_TYPE_IPV4_IFINDEX, /* IPv4 nexthop with ifindex. */
71995 - NEXTHOP_TYPE_IPV4_IFNAME, /* IPv4 nexthop with ifname. */
71996 - NEXTHOP_TYPE_IPV6, /* IPv6 nexthop. */
71997 - NEXTHOP_TYPE_IPV6_IFINDEX, /* IPv6 nexthop with ifindex. */
71998 - NEXTHOP_TYPE_IPV6_IFNAME, /* IPv6 nexthop with ifname. */
71999 - NEXTHOP_TYPE_BLACKHOLE, /* Null0 nexthop. */
72000 + struct zapi_nexthop nh;
72003 /* Nexthop structure. */
72004 @@ -176,17 +117,24 @@
72006 struct nexthop *next;
72007 struct nexthop *prev;
72008 + struct nexthop *tied;
72010 /* Interface index. */
72011 char *ifname;
72012 unsigned int ifindex;
72014 - enum nexthop_types_t type;
72015 + unsigned int mpls;
72016 + unsigned int type;
72017 + unsigned int advmss;
72019 u_char flags;
72020 #define NEXTHOP_FLAG_ACTIVE (1 << 0) /* This nexthop is alive. */
72021 #define NEXTHOP_FLAG_FIB (1 << 1) /* FIB nexthop. */
72022 #define NEXTHOP_FLAG_RECURSIVE (1 << 2) /* Recursive nexthop. */
72023 +#define NEXTHOP_FLAG_IGNORE (1 << 3) /* Ignore this nexthop */
72025 + /* the type of drop (REJECT, BLACKHOLE, NULL) */
72026 + u_char drop;
72028 /* Nexthop address or interface name. */
72029 union g_addr gate;
72030 @@ -196,6 +144,7 @@
72031 unsigned int rifindex;
72032 union g_addr rgate;
72033 union g_addr src;
72034 + unsigned int rmpls;
72037 /* Routing table instance. */
72038 @@ -220,86 +169,72 @@
72039 struct route_table *stable[AFI_MAX][SAFI_MAX];
72042 -extern struct nexthop *nexthop_ifindex_add (struct rib *, unsigned int);
72043 -extern struct nexthop *nexthop_ifname_add (struct rib *, char *);
72044 -extern struct nexthop *nexthop_blackhole_add (struct rib *);
72045 -extern struct nexthop *nexthop_ipv4_add (struct rib *, struct in_addr *,
72046 - struct in_addr *);
72047 +extern void
72048 +nexthop_delete (struct rib *rib, struct nexthop *nexthop);
72050 +extern void
72051 +nexthop_free (struct nexthop *nexthop);
72053 +extern struct nexthop *nexthop_zapi_nexthop_add(struct rib *rib,
72054 + struct zapi_nexthop* znh);
72055 +extern void zapi_nexthop2nexthop(struct zapi_nexthop* znh, struct nexthop *nh);
72057 extern void rib_lookup_and_dump (struct prefix_ipv4 *);
72058 extern void rib_lookup_and_pushup (struct prefix_ipv4 *);
72059 extern void rib_dump (const char *, const struct prefix_ipv4 *, const struct rib *);
72060 -extern int rib_lookup_ipv4_route (struct prefix_ipv4 *, union sockunion *);
72061 +extern int rib_lookup_route_nexthop (struct prefix *, struct zapi_nexthop *);
72062 #define ZEBRA_RIB_LOOKUP_ERROR -1
72063 #define ZEBRA_RIB_FOUND_EXACT 0
72064 #define ZEBRA_RIB_FOUND_NOGATE 1
72065 #define ZEBRA_RIB_FOUND_CONNECTED 2
72066 #define ZEBRA_RIB_NOTFOUND 3
72068 -#ifdef HAVE_IPV6
72069 -extern struct nexthop *nexthop_ipv6_add (struct rib *, struct in6_addr *);
72070 -#endif /* HAVE_IPV6 */
72072 extern struct vrf *vrf_lookup (u_int32_t);
72073 extern struct route_table *vrf_table (afi_t afi, safi_t safi, u_int32_t id);
72074 extern struct route_table *vrf_static_table (afi_t afi, safi_t safi, u_int32_t id);
72076 /* NOTE:
72077 - * All rib_add_ipv[46]* functions will not just add prefix into RIB, but
72078 + * All rib_add_route function will not just add prefix into RIB, but
72079 * also implicitly withdraw equal prefix of same type. */
72080 -extern int rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
72081 - struct in_addr *gate, struct in_addr *src,
72082 - unsigned int ifindex, u_int32_t vrf_id,
72083 - u_int32_t, u_char);
72084 +extern int rib_add_route (int type, int flags, struct prefix *p,
72085 + struct zapi_nexthop *nh, u_int32_t vrf_id,
72086 + u_int32_t, u_char);
72088 -extern int rib_add_ipv4_multipath (struct prefix_ipv4 *, struct rib *);
72089 +extern int rib_delete_route (int type, int flags, struct prefix *p,
72090 + struct zapi_nexthop *nh, u_int32_t);
72091 +extern int
72092 +rib_find_nexthop2 (int owner, struct rib *rib_in, struct nexthop *nh_in,
72093 + struct rib **rib_out, struct nexthop **nh_out);
72095 +extern int
72096 +rib_find_nexthop (int owner, struct prefix *p_in, struct nexthop *nh_in,
72097 + struct route_node **rn_out, struct rib **rib_out,
72098 + struct nexthop **nh_out);
72100 -extern int rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
72101 - struct in_addr *gate, unsigned int ifindex,
72102 - u_int32_t);
72103 +extern int rib_add_multipath (struct prefix *, struct rib *);
72105 -extern struct rib *rib_match_ipv4 (struct in_addr);
72106 +extern struct rib *rib_match_route (struct prefix *p);
72108 -extern struct rib *rib_lookup_ipv4 (struct prefix_ipv4 *);
72109 +extern struct rib *rib_lookup_route (struct prefix *);
72111 +extern int rib_check_drop (struct rib *);
72112 extern void rib_update (void);
72113 extern void rib_weed_tables (void);
72114 extern void rib_sweep_route (void);
72115 extern void rib_close (void);
72116 extern void rib_init (void);
72117 +extern int rib_uninstall_kernel (struct route_node *rn, struct rib *rib);
72119 extern int
72120 -static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
72121 - u_char flags, u_char distance, u_int32_t vrf_id);
72122 +static_add_route (struct prefix *p, struct zapi_nexthop *nh,
72123 + u_char distance, u_int32_t vrf_id);
72125 extern int
72126 -static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
72127 - u_char distance, u_int32_t vrf_id);
72128 +static_delete_route (struct prefix *p, struct zapi_nexthop *nh,
72129 + u_char distance, u_int32_t vrf_id);
72131 #ifdef HAVE_IPV6
72132 -extern int
72133 -rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
72134 - struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
72135 - u_int32_t metric, u_char distance);
72137 -extern int
72138 -rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
72139 - struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id);
72141 -extern struct rib *rib_lookup_ipv6 (struct in6_addr *);
72143 -extern struct rib *rib_match_ipv6 (struct in6_addr *);
72145 extern struct route_table *rib_table_ipv6;
72147 -extern int
72148 -static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
72149 - const char *ifname, u_char flags, u_char distance,
72150 - u_int32_t vrf_id);
72152 -extern int
72153 -static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
72154 - const char *ifname, u_char distance, u_int32_t vrf_id);
72156 #endif /* HAVE_IPV6 */
72158 #endif /*_ZEBRA_RIB_H */
72159 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/rt_ioctl.c quagga-mpls/zebra/rt_ioctl.c
72160 --- quagga/zebra/rt_ioctl.c 2007-05-09 15:59:35.000000000 -0500
72161 +++ quagga-mpls/zebra/rt_ioctl.c 2008-02-19 22:55:41.000000000 -0600
72162 @@ -206,8 +206,7 @@
72164 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
72166 - if (nexthop->rtype == NEXTHOP_TYPE_IPV4 ||
72167 - nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
72168 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV4))
72170 sin_gate.sin_family = AF_INET;
72171 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
72172 @@ -216,8 +215,16 @@
72173 sin_gate.sin_addr = nexthop->rgate.ipv4;
72174 rtentry.rt_flags |= RTF_GATEWAY;
72176 - if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
72177 - || nexthop->rtype == NEXTHOP_TYPE_IFNAME)
72178 + else if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV6))
72180 + assert (0);
72182 + else if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_DROP))
72184 + SET_FLAG (rtentry.rt_flags, RTF_REJECT);
72187 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IFINDEX))
72189 ifp = if_lookup_by_index (nexthop->rifindex);
72190 if (ifp)
72191 @@ -225,11 +232,14 @@
72192 else
72193 return -1;
72195 + else if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IFNAME))
72197 + assert (0);
72200 else
72202 - if (nexthop->type == NEXTHOP_TYPE_IPV4 ||
72203 - nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
72204 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV4))
72206 sin_gate.sin_family = AF_INET;
72207 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
72208 @@ -238,8 +248,16 @@
72209 sin_gate.sin_addr = nexthop->gate.ipv4;
72210 rtentry.rt_flags |= RTF_GATEWAY;
72212 - if (nexthop->type == NEXTHOP_TYPE_IFINDEX
72213 - || nexthop->type == NEXTHOP_TYPE_IFNAME)
72214 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV6))
72216 + assert (0);
72218 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_DROP))
72220 + SET_FLAG (rtentry.rt_flags, RTF_REJECT);
72223 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX))
72225 ifp = if_lookup_by_index (nexthop->ifindex);
72226 if (ifp)
72227 @@ -247,6 +265,10 @@
72228 else
72229 return -1;
72231 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFNAME))
72233 + assert (0);
72237 if (cmd == SIOCADDRT)
72238 @@ -465,17 +487,21 @@
72240 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
72242 - if (nexthop->rtype == NEXTHOP_TYPE_IPV6
72243 - || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME
72244 - || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX)
72245 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV6))
72247 memcpy (&rtm.rtmsg_gateway, &nexthop->rgate.ipv6,
72248 sizeof (struct in6_addr));
72250 - if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
72251 - || nexthop->rtype == NEXTHOP_TYPE_IFNAME
72252 - || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME
72253 - || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX)
72254 + else if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV4))
72256 + assert (0);
72258 + else if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_DROP))
72260 + SET_FLAG (rtentry.rt_flags, RTF_REJECT);
72263 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IFINDEX))
72264 rtm.rtmsg_ifindex = nexthop->rifindex;
72265 else
72266 rtm.rtmsg_ifindex = 0;
72267 @@ -483,17 +509,21 @@
72269 else
72271 - if (nexthop->type == NEXTHOP_TYPE_IPV6
72272 - || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
72273 - || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
72274 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV6))
72276 memcpy (&rtm.rtmsg_gateway, &nexthop->gate.ipv6,
72277 sizeof (struct in6_addr));
72279 - if (nexthop->type == NEXTHOP_TYPE_IFINDEX
72280 - || nexthop->type == NEXTHOP_TYPE_IFNAME
72281 - || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
72282 - || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
72283 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV4))
72285 + assert (0);
72287 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_DROP))
72289 + SET_FLAG (rtentry.rt_flags, RTF_REJECT);
72292 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX))
72293 rtm.rtmsg_ifindex = nexthop->ifindex;
72294 else
72295 rtm.rtmsg_ifindex = 0;
72296 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/rt_netlink.c quagga-mpls/zebra/rt_netlink.c
72297 --- quagga/zebra/rt_netlink.c 2008-09-04 20:37:37.000000000 -0500
72298 +++ quagga-mpls/zebra/rt_netlink.c 2008-09-07 20:23:37.000000000 -0500
72299 @@ -35,56 +35,26 @@
72300 #include "rib.h"
72301 #include "thread.h"
72302 #include "privs.h"
72303 +#ifdef HAVE_MPLS
72304 +#include "mpls_lib.h"
72305 +#ifdef LINUX_MPLS
72306 +#include <linux/shim.h>
72307 +#endif
72308 +#endif /* HAVE_MPLS */
72310 +#include "zebra/rt.h"
72311 #include "zebra/zserv.h"
72312 #include "zebra/rt.h"
72313 #include "zebra/redistribute.h"
72314 #include "zebra/interface.h"
72315 #include "zebra/debug.h"
72316 +#include "zebra/netlink.h"
72317 +#include "zebra/rt_netlink.h"
72319 /* Socket interface to kernel */
72320 -struct nlsock
72322 - int sock;
72323 - int seq;
72324 - struct sockaddr_nl snl;
72325 - const char *name;
72326 -} netlink = { -1, 0, {0}, "netlink-listen"}, /* kernel messages */
72327 - netlink_cmd = { -1, 0, {0}, "netlink-cmd"}; /* command channel */
72329 -struct message nlmsg_str[] = {
72330 - {RTM_NEWROUTE, "RTM_NEWROUTE"},
72331 - {RTM_DELROUTE, "RTM_DELROUTE"},
72332 - {RTM_GETROUTE, "RTM_GETROUTE"},
72333 - {RTM_NEWLINK, "RTM_NEWLINK"},
72334 - {RTM_DELLINK, "RTM_DELLINK"},
72335 - {RTM_GETLINK, "RTM_GETLINK"},
72336 - {RTM_NEWADDR, "RTM_NEWADDR"},
72337 - {RTM_DELADDR, "RTM_DELADDR"},
72338 - {RTM_GETADDR, "RTM_GETADDR"},
72339 - {0, NULL}
72342 -const char *nexthop_types_desc[] =
72344 - "none",
72345 - "Directly connected",
72346 - "Interface route",
72347 - "IPv4 nexthop",
72348 - "IPv4 nexthop with ifindex",
72349 - "IPv4 nexthop with ifname",
72350 - "IPv6 nexthop",
72351 - "IPv6 nexthop with ifindex",
72352 - "IPv6 nexthop with ifname",
72353 - "Null0 nexthop",
72357 -extern struct zebra_t zebrad;
72359 -extern struct zebra_privs_t zserv_privs;
72361 -extern u_int32_t nl_rcvbufsize;
72362 +static struct nlsock
72363 + netlink = { -1, 0, {0}, "netlink-listen", 0}, /* kernel messages */
72364 + netlink_cmd = { -1, 0, {0}, "netlink-cmd", 1}; /* command channel */
72366 /* Note: on netlink systems, there should be a 1-to-1 mapping between interface
72367 names and ifindex values. */
72368 @@ -113,388 +83,10 @@
72369 ifp->ifindex = ifi_index;
72372 -/* Make socket for Linux netlink interface. */
72373 -static int
72374 -netlink_socket (struct nlsock *nl, unsigned long groups)
72376 - int ret;
72377 - struct sockaddr_nl snl;
72378 - int sock;
72379 - int namelen;
72380 - int save_errno;
72382 - sock = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
72383 - if (sock < 0)
72385 - zlog (NULL, LOG_ERR, "Can't open %s socket: %s", nl->name,
72386 - safe_strerror (errno));
72387 - return -1;
72390 - ret = fcntl (sock, F_SETFL, O_NONBLOCK);
72391 - if (ret < 0)
72393 - zlog (NULL, LOG_ERR, "Can't set %s socket flags: %s", nl->name,
72394 - safe_strerror (errno));
72395 - close (sock);
72396 - return -1;
72399 - /* Set receive buffer size if it's set from command line */
72400 - if (nl_rcvbufsize)
72402 - u_int32_t oldsize, oldlen;
72403 - u_int32_t newsize, newlen;
72405 - oldlen = sizeof(oldsize);
72406 - newlen = sizeof(newsize);
72408 - ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldlen);
72409 - if (ret < 0)
72411 - zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name,
72412 - safe_strerror (errno));
72413 - close (sock);
72414 - return -1;
72417 - ret = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &nl_rcvbufsize,
72418 - sizeof(nl_rcvbufsize));
72419 - if (ret < 0)
72421 - zlog (NULL, LOG_ERR, "Can't set %s receive buffer size: %s", nl->name,
72422 - safe_strerror (errno));
72423 - close (sock);
72424 - return -1;
72427 - ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen);
72428 - if (ret < 0)
72430 - zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name,
72431 - safe_strerror (errno));
72432 - close (sock);
72433 - return -1;
72436 - zlog (NULL, LOG_INFO,
72437 - "Setting netlink socket receive buffer size: %u -> %u",
72438 - oldsize, newsize);
72441 - memset (&snl, 0, sizeof snl);
72442 - snl.nl_family = AF_NETLINK;
72443 - snl.nl_groups = groups;
72445 - /* Bind the socket to the netlink structure for anything. */
72446 - if (zserv_privs.change (ZPRIVS_RAISE))
72448 - zlog (NULL, LOG_ERR, "Can't raise privileges");
72449 - return -1;
72452 - ret = bind (sock, (struct sockaddr *) &snl, sizeof snl);
72453 - save_errno = errno;
72454 - if (zserv_privs.change (ZPRIVS_LOWER))
72455 - zlog (NULL, LOG_ERR, "Can't lower privileges");
72457 - if (ret < 0)
72459 - zlog (NULL, LOG_ERR, "Can't bind %s socket to group 0x%x: %s",
72460 - nl->name, snl.nl_groups, safe_strerror (save_errno));
72461 - close (sock);
72462 - return -1;
72465 - /* multiple netlink sockets will have different nl_pid */
72466 - namelen = sizeof snl;
72467 - ret = getsockname (sock, (struct sockaddr *) &snl, (socklen_t *) &namelen);
72468 - if (ret < 0 || namelen != sizeof snl)
72470 - zlog (NULL, LOG_ERR, "Can't get %s socket name: %s", nl->name,
72471 - safe_strerror (errno));
72472 - close (sock);
72473 - return -1;
72476 - nl->snl = snl;
72477 - nl->sock = sock;
72478 - return ret;
72481 -int
72482 -set_netlink_blocking (struct nlsock *nl, int *flags)
72485 - /* Change socket flags for blocking I/O. */
72486 - if ((*flags = fcntl (nl->sock, F_GETFL, 0)) < 0)
72488 - zlog (NULL, LOG_ERR, "%s:%i F_GETFL error: %s",
72489 - __FUNCTION__, __LINE__, safe_strerror (errno));
72490 - return -1;
72492 - *flags &= ~O_NONBLOCK;
72493 - if (fcntl (nl->sock, F_SETFL, *flags) < 0)
72495 - zlog (NULL, LOG_ERR, "%s:%i F_SETFL error: %s",
72496 - __FUNCTION__, __LINE__, safe_strerror (errno));
72497 - return -1;
72499 - return 0;
72502 -int
72503 -set_netlink_nonblocking (struct nlsock *nl, int *flags)
72505 - /* Restore socket flags for nonblocking I/O */
72506 - *flags |= O_NONBLOCK;
72507 - if (fcntl (nl->sock, F_SETFL, *flags) < 0)
72509 - zlog (NULL, LOG_ERR, "%s:%i F_SETFL error: %s",
72510 - __FUNCTION__, __LINE__, safe_strerror (errno));
72511 - return -1;
72513 - return 0;
72516 -/* Get type specified information from netlink. */
72517 -static int
72518 -netlink_request (int family, int type, struct nlsock *nl)
72520 - int ret;
72521 - struct sockaddr_nl snl;
72522 - int save_errno;
72524 - struct
72526 - struct nlmsghdr nlh;
72527 - struct rtgenmsg g;
72528 - } req;
72531 - /* Check netlink socket. */
72532 - if (nl->sock < 0)
72534 - zlog (NULL, LOG_ERR, "%s socket isn't active.", nl->name);
72535 - return -1;
72538 - memset (&snl, 0, sizeof snl);
72539 - snl.nl_family = AF_NETLINK;
72541 - memset (&req, 0, sizeof req);
72542 - req.nlh.nlmsg_len = sizeof req;
72543 - req.nlh.nlmsg_type = type;
72544 - req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
72545 - req.nlh.nlmsg_pid = 0;
72546 - req.nlh.nlmsg_seq = ++nl->seq;
72547 - req.g.rtgen_family = family;
72549 - /* linux appears to check capabilities on every message
72550 - * have to raise caps for every message sent
72551 - */
72552 - if (zserv_privs.change (ZPRIVS_RAISE))
72554 - zlog (NULL, LOG_ERR, "Can't raise privileges");
72555 - return -1;
72558 - ret = sendto (nl->sock, (void *) &req, sizeof req, 0,
72559 - (struct sockaddr *) &snl, sizeof snl);
72560 - save_errno = errno;
72562 - if (zserv_privs.change (ZPRIVS_LOWER))
72563 - zlog (NULL, LOG_ERR, "Can't lower privileges");
72565 - if (ret < 0)
72567 - zlog (NULL, LOG_ERR, "%s sendto failed: %s", nl->name,
72568 - safe_strerror (save_errno));
72569 - return -1;
72572 - return 0;
72575 -/* Receive message from netlink interface and pass those information
72576 - to the given function. */
72577 -static int
72578 -netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
72579 - struct nlsock *nl)
72581 - int status;
72582 - int ret = 0;
72583 - int error;
72585 - while (1)
72587 - char buf[4096];
72588 - struct iovec iov = { buf, sizeof buf };
72589 - struct sockaddr_nl snl;
72590 - struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
72591 - struct nlmsghdr *h;
72592 - int save_errno;
72594 - if (zserv_privs.change (ZPRIVS_RAISE))
72595 - zlog (NULL, LOG_ERR, "Can't raise privileges");
72597 - status = recvmsg (nl->sock, &msg, 0);
72598 - save_errno = errno;
72600 - if (zserv_privs.change (ZPRIVS_LOWER))
72601 - zlog (NULL, LOG_ERR, "Can't lower privileges");
72603 - if (status < 0)
72605 - if (save_errno == EINTR)
72606 - continue;
72607 - if (save_errno == EWOULDBLOCK || save_errno == EAGAIN)
72608 - break;
72609 - zlog (NULL, LOG_ERR, "%s recvmsg overrun: %s",
72610 - nl->name, safe_strerror(save_errno));
72611 - continue;
72614 - if (status == 0)
72616 - zlog (NULL, LOG_ERR, "%s EOF", nl->name);
72617 - return -1;
72620 - if (msg.msg_namelen != sizeof snl)
72622 - zlog (NULL, LOG_ERR, "%s sender address length error: length %d",
72623 - nl->name, msg.msg_namelen);
72624 - return -1;
72627 - /* JF: Ignore messages that aren't from the kernel */
72628 - if ( snl.nl_pid != 0 )
72630 - zlog ( NULL, LOG_ERR, "Ignoring message from pid %u", snl.nl_pid );
72631 - continue;
72634 - for (h = (struct nlmsghdr *) buf; NLMSG_OK (h, (unsigned int) status);
72635 - h = NLMSG_NEXT (h, status))
72637 - /* Finish of reading. */
72638 - if (h->nlmsg_type == NLMSG_DONE)
72639 - return ret;
72641 - /* Error handling. */
72642 - if (h->nlmsg_type == NLMSG_ERROR)
72644 - struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h);
72646 - /* If the error field is zero, then this is an ACK */
72647 - if (err->error == 0)
72649 - if (IS_ZEBRA_DEBUG_KERNEL)
72651 - zlog_debug ("%s: %s ACK: type=%s(%u), seq=%u, pid=%u",
72652 - __FUNCTION__, nl->name,
72653 - lookup (nlmsg_str, err->msg.nlmsg_type),
72654 - err->msg.nlmsg_type, err->msg.nlmsg_seq,
72655 - err->msg.nlmsg_pid);
72658 - /* return if not a multipart message, otherwise continue */
72659 - if (!(h->nlmsg_flags & NLM_F_MULTI))
72661 - return 0;
72663 - continue;
72666 - if (h->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr)))
72668 - zlog (NULL, LOG_ERR, "%s error: message truncated",
72669 - nl->name);
72670 - return -1;
72673 - /* Deal with Error Noise - MAG */
72675 - int loglvl = LOG_ERR;
72676 - int errnum = err->error;
72677 - int msg_type = err->msg.nlmsg_type;
72679 - if (nl == &netlink_cmd
72680 - && (-errnum == ENODEV || -errnum == ESRCH)
72681 - && (msg_type == RTM_NEWROUTE || msg_type == RTM_DELROUTE))
72682 - loglvl = LOG_DEBUG;
72684 - zlog (NULL, loglvl, "%s error: %s, type=%s(%u), "
72685 - "seq=%u, pid=%u",
72686 - nl->name, safe_strerror (-errnum),
72687 - lookup (nlmsg_str, msg_type),
72688 - msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid);
72690 - /*
72691 - ret = -1;
72692 - continue;
72693 - */
72694 - return -1;
72697 - /* OK we got netlink message. */
72698 - if (IS_ZEBRA_DEBUG_KERNEL)
72699 - zlog_debug ("netlink_parse_info: %s type %s(%u), seq=%u, pid=%u",
72700 - nl->name,
72701 - lookup (nlmsg_str, h->nlmsg_type), h->nlmsg_type,
72702 - h->nlmsg_seq, h->nlmsg_pid);
72704 - /* skip unsolicited messages originating from command socket */
72705 - if (nl != &netlink_cmd && h->nlmsg_pid == netlink_cmd.snl.nl_pid)
72707 - if (IS_ZEBRA_DEBUG_KERNEL)
72708 - zlog_debug ("netlink_parse_info: %s packet comes from %s",
72709 - netlink_cmd.name, nl->name);
72710 - continue;
72713 - error = (*filter) (&snl, h);
72714 - if (error < 0)
72716 - zlog (NULL, LOG_ERR, "%s filter function error", nl->name);
72717 - ret = error;
72721 - /* After error care. */
72722 - if (msg.msg_flags & MSG_TRUNC)
72724 - zlog (NULL, LOG_ERR, "%s error: message truncated", nl->name);
72725 - continue;
72727 - if (status)
72729 - zlog (NULL, LOG_ERR, "%s error: data remnant size %d", nl->name,
72730 - status);
72731 - return -1;
72734 - return ret;
72737 -/* Utility function for parse rtattr. */
72738 -static void
72739 -netlink_parse_rtattr (struct rtattr **tb, int max, struct rtattr *rta,
72740 - int len)
72742 - while (RTA_OK (rta, len))
72744 - if (rta->rta_type <= max)
72745 - tb[rta->rta_type] = rta;
72746 - rta = RTA_NEXT (rta, len);
72750 /* Called from interface_lookup_netlink(). This function is only used
72751 during bootstrap. */
72752 -int
72753 -netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h)
72754 +static int
72755 +netlink_interface (struct nlsock *nl, struct sockaddr_nl *snl, struct nlmsghdr *h)
72757 int len;
72758 struct ifinfomsg *ifi;
72759 @@ -503,6 +95,15 @@
72760 char *name;
72761 int i;
72763 + /* skip unsolicited messages originating from command socket */
72764 + if ((!nl->cmd) && h->nlmsg_pid == netlink_cmd.snl.nl_pid)
72766 + if (IS_ZEBRA_DEBUG_KERNEL)
72767 + zlog_debug ("netlink_parse_info: %s packet comes from %s",
72768 + netlink_cmd.name, nl->name);
72769 + return 0;
72772 ifi = NLMSG_DATA (h);
72774 if (h->nlmsg_type != RTM_NEWLINK)
72775 @@ -570,8 +171,8 @@
72778 /* Lookup interface IPv4/IPv6 address. */
72779 -int
72780 -netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
72781 +static int
72782 +netlink_interface_addr (struct nlsock *nl, struct sockaddr_nl *snl, struct nlmsghdr *h)
72784 int len;
72785 struct ifaddrmsg *ifa;
72786 @@ -582,6 +183,15 @@
72787 u_char flags = 0;
72788 char *label = NULL;
72790 + /* skip unsolicited messages originating from command socket */
72791 + if ((!nl->cmd) && h->nlmsg_pid == netlink_cmd.snl.nl_pid)
72793 + if (IS_ZEBRA_DEBUG_KERNEL)
72794 + zlog_debug ("netlink_parse_info: %s packet comes from %s",
72795 + netlink_cmd.name, nl->name);
72796 + return 0;
72799 ifa = NLMSG_DATA (h);
72801 if (ifa->ifa_family != AF_INET
72802 @@ -705,13 +315,14 @@
72805 /* Looking up routing table by netlink interface. */
72806 -int
72807 -netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
72808 +static int
72809 +netlink_routing_table (struct nlsock *nl, struct sockaddr_nl *snl, struct nlmsghdr *h)
72811 int len;
72812 struct rtmsg *rtm;
72813 struct rtattr *tb[RTA_MAX + 1];
72814 - u_char flags = 0;
72815 + u_short zebra_flags = 0;
72816 + struct zapi_nexthop nh;
72818 char anyaddr[16] = { 0 };
72820 @@ -723,6 +334,17 @@
72821 void *gate;
72822 void *src;
72824 + memset(&nh, 0, sizeof(struct zapi_nexthop));
72826 + /* skip unsolicited messages originating from command socket */
72827 + if ((!nl->cmd) && h->nlmsg_pid == netlink_cmd.snl.nl_pid)
72829 + if (IS_ZEBRA_DEBUG_KERNEL)
72830 + zlog_debug ("netlink_parse_info: %s packet comes from %s",
72831 + netlink_cmd.name, nl->name);
72832 + return 0;
72835 rtm = NLMSG_DATA (h);
72837 if (h->nlmsg_type != RTM_NEWROUTE)
72838 @@ -755,7 +377,7 @@
72840 /* Route which inserted by Zebra. */
72841 if (rtm->rtm_protocol == RTPROT_ZEBRA)
72842 - flags |= ZEBRA_FLAG_SELFROUTE;
72843 + zebra_flags |= ZEBRA_FLAG_SELFROUTE;
72845 index = 0;
72846 metric = 0;
72847 @@ -764,7 +386,11 @@
72848 src = NULL;
72850 if (tb[RTA_OIF])
72851 - index = *(int *) RTA_DATA (tb[RTA_OIF]);
72853 + index = *(int *) RTA_DATA (tb[RTA_OIF]);
72854 + nh.intf.index = index;
72855 + SET_FLAG(nh.type, ZEBRA_NEXTHOP_IFINDEX);
72858 if (tb[RTA_DST])
72859 dest = RTA_DATA (tb[RTA_DST]);
72860 @@ -776,7 +402,9 @@
72862 /* Multipath treatment is needed. */
72863 if (tb[RTA_GATEWAY])
72864 - gate = RTA_DATA (tb[RTA_GATEWAY]);
72866 + gate = RTA_DATA (tb[RTA_GATEWAY]);
72869 if (tb[RTA_PRIORITY])
72870 metric = *(int *) RTA_DATA(tb[RTA_PRIORITY]);
72871 @@ -788,7 +416,20 @@
72872 memcpy (&p.prefix, dest, 4);
72873 p.prefixlen = rtm->rtm_dst_len;
72875 - rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, src, index, table, metric, 0);
72876 + if (gate)
72878 + memcpy(&nh.gw.ipv4, gate, sizeof(struct in_addr));
72879 + SET_FLAG(nh.type, ZEBRA_NEXTHOP_IPV4);
72882 + if (src)
72884 + memcpy(&nh.src.ipv4, src, sizeof(struct in_addr));
72885 + SET_FLAG(nh.type, ZEBRA_NEXTHOP_SRC_IPV4);
72888 + rib_add_route (ZEBRA_ROUTE_KERNEL, zebra_flags, (struct prefix*)&p,
72889 + &nh, table, metric, 0);
72891 #ifdef HAVE_IPV6
72892 if (rtm->rtm_family == AF_INET6)
72893 @@ -798,8 +439,14 @@
72894 memcpy (&p.prefix, dest, 16);
72895 p.prefixlen = rtm->rtm_dst_len;
72897 - rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table,
72898 - metric, 0);
72899 + if (gate)
72901 + memcpy(&nh.gw.ipv6, gate, sizeof(struct in6_addr));
72902 + SET_FLAG(nh.type, ZEBRA_NEXTHOP_IPV6);
72905 + rib_add_route (ZEBRA_ROUTE_KERNEL, zebra_flags, (struct prefix*)&p,
72906 + &nh, table, metric, 0);
72908 #endif /* HAVE_IPV6 */
72910 @@ -822,12 +469,13 @@
72913 /* Routing information change from the kernel. */
72914 -int
72915 -netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
72916 +static int
72917 +netlink_route_change (struct nlsock *nl, struct sockaddr_nl *snl, struct nlmsghdr *h)
72919 int len;
72920 struct rtmsg *rtm;
72921 struct rtattr *tb[RTA_MAX + 1];
72922 + struct zapi_nexthop nh;
72924 char anyaddr[16] = { 0 };
72926 @@ -837,6 +485,17 @@
72927 void *gate;
72928 void *src;
72930 + memset(&nh, 0, sizeof(struct zapi_nexthop));
72932 + /* skip unsolicited messages originating from command socket */
72933 + if ((!nl->cmd) && h->nlmsg_pid == netlink_cmd.snl.nl_pid)
72935 + if (IS_ZEBRA_DEBUG_KERNEL)
72936 + zlog_debug ("netlink_parse_info: %s packet comes from %s",
72937 + netlink_cmd.name, nl->name);
72938 + return 0;
72941 rtm = NLMSG_DATA (h);
72943 if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE))
72944 @@ -895,7 +554,11 @@
72945 src = NULL;
72947 if (tb[RTA_OIF])
72948 - index = *(int *) RTA_DATA (tb[RTA_OIF]);
72950 + index = *(int *) RTA_DATA (tb[RTA_OIF]);
72951 + nh.intf.index = index;
72952 + SET_FLAG(nh.type, ZEBRA_NEXTHOP_IFINDEX);
72955 if (tb[RTA_DST])
72956 dest = RTA_DATA (tb[RTA_DST]);
72957 @@ -925,10 +588,24 @@
72958 inet_ntoa (p.prefix), p.prefixlen);
72961 + if (gate)
72963 + memcpy(&nh.gw.ipv4, gate, sizeof(struct in_addr));
72964 + SET_FLAG(nh.type, ZEBRA_NEXTHOP_IPV4);
72967 + if (src)
72969 + memcpy(&nh.src.ipv4, src, sizeof(struct in_addr));
72970 + SET_FLAG(nh.type, ZEBRA_NEXTHOP_SRC_IPV4);
72973 if (h->nlmsg_type == RTM_NEWROUTE)
72974 - rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, src, index, table, 0, 0);
72975 + rib_add_route (ZEBRA_ROUTE_KERNEL, 0, (struct prefix*)&p,
72976 + &nh, table, 0, 0);
72977 else
72978 - rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table);
72979 + rib_delete_route (ZEBRA_ROUTE_KERNEL, 0, (struct prefix*)&p,
72980 + &nh, table);
72983 #ifdef HAVE_IPV6
72984 @@ -953,18 +630,24 @@
72985 p.prefixlen);
72988 + if (gate)
72990 + memcpy(&nh.gw.ipv6, gate, sizeof(struct in6_addr));
72991 + SET_FLAG(nh.type, ZEBRA_NEXTHOP_IPV6);
72994 if (h->nlmsg_type == RTM_NEWROUTE)
72995 - rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, 0, 0, 0);
72996 + rib_add_route (ZEBRA_ROUTE_KERNEL, 0, (struct prefix*)&p, &nh, 0, 0, 0);
72997 else
72998 - rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, 0);
72999 + rib_delete_route (ZEBRA_ROUTE_KERNEL, 0, (struct prefix*)&p, &nh, 0);
73001 #endif /* HAVE_IPV6 */
73003 return 0;
73006 -int
73007 -netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
73008 +static int
73009 +netlink_link_change (struct nlsock *nl, struct sockaddr_nl *snl, struct nlmsghdr *h)
73011 int len;
73012 struct ifinfomsg *ifi;
73013 @@ -974,6 +657,15 @@
73015 ifi = NLMSG_DATA (h);
73017 + /* skip unsolicited messages originating from command socket */
73018 + if ((!nl->cmd) && h->nlmsg_pid == netlink_cmd.snl.nl_pid)
73020 + if (IS_ZEBRA_DEBUG_KERNEL)
73021 + zlog_debug ("netlink_parse_info: %s packet comes from %s",
73022 + netlink_cmd.name, nl->name);
73023 + return 0;
73026 if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK))
73028 /* If this is not link add/delete message so print warning. */
73029 @@ -1064,28 +756,37 @@
73030 return 0;
73033 -int
73034 -netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h)
73035 +static int
73036 +netlink_information_fetch (struct nlsock *nl, struct sockaddr_nl *snl, struct nlmsghdr *h)
73038 + /* skip unsolicited messages originating from command socket */
73039 + if ((!nl->cmd) && h->nlmsg_pid == netlink_cmd.snl.nl_pid)
73041 + if (IS_ZEBRA_DEBUG_KERNEL)
73042 + zlog_debug ("netlink_parse_info: %s packet comes from %s",
73043 + netlink_cmd.name, nl->name);
73044 + return 0;
73047 switch (h->nlmsg_type)
73049 case RTM_NEWROUTE:
73050 - return netlink_route_change (snl, h);
73051 + return netlink_route_change (nl, snl, h);
73052 break;
73053 case RTM_DELROUTE:
73054 - return netlink_route_change (snl, h);
73055 + return netlink_route_change (nl, snl, h);
73056 break;
73057 case RTM_NEWLINK:
73058 - return netlink_link_change (snl, h);
73059 + return netlink_link_change (nl, snl, h);
73060 break;
73061 case RTM_DELLINK:
73062 - return netlink_link_change (snl, h);
73063 + return netlink_link_change (nl, snl, h);
73064 break;
73065 case RTM_NEWADDR:
73066 - return netlink_interface_addr (snl, h);
73067 + return netlink_interface_addr (nl, snl, h);
73068 break;
73069 case RTM_DELADDR:
73070 - return netlink_interface_addr (snl, h);
73071 + return netlink_interface_addr (nl, snl, h);
73072 break;
73073 default:
73074 zlog_warn ("Unknown netlink nlmsg_type %d\n", h->nlmsg_type);
73075 @@ -1116,7 +817,7 @@
73076 ret = netlink_request (AF_PACKET, RTM_GETLINK, &netlink_cmd);
73077 if (ret < 0)
73078 return ret;
73079 - ret = netlink_parse_info (netlink_interface, &netlink_cmd);
73080 + ret = netlink_parse_info (netlink_interface, &netlink_cmd, NULL, 0);
73081 if (ret < 0)
73082 return ret;
73084 @@ -1124,7 +825,7 @@
73085 ret = netlink_request (AF_INET, RTM_GETADDR, &netlink_cmd);
73086 if (ret < 0)
73087 return ret;
73088 - ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd);
73089 + ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd, NULL, 0);
73090 if (ret < 0)
73091 return ret;
73093 @@ -1133,7 +834,7 @@
73094 ret = netlink_request (AF_INET6, RTM_GETADDR, &netlink_cmd);
73095 if (ret < 0)
73096 return ret;
73097 - ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd);
73098 + ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd, NULL, 0);
73099 if (ret < 0)
73100 return ret;
73101 #endif /* HAVE_IPV6 */
73102 @@ -1167,7 +868,7 @@
73103 ret = netlink_request (AF_INET, RTM_GETROUTE, &netlink_cmd);
73104 if (ret < 0)
73105 return ret;
73106 - ret = netlink_parse_info (netlink_routing_table, &netlink_cmd);
73107 + ret = netlink_parse_info (netlink_routing_table, &netlink_cmd, NULL, 0);
73108 if (ret < 0)
73109 return ret;
73111 @@ -1176,7 +877,7 @@
73112 ret = netlink_request (AF_INET6, RTM_GETROUTE, &netlink_cmd);
73113 if (ret < 0)
73114 return ret;
73115 - ret = netlink_parse_info (netlink_routing_table, &netlink_cmd);
73116 + ret = netlink_parse_info (netlink_routing_table, &netlink_cmd, NULL, 0);
73117 if (ret < 0)
73118 return ret;
73119 #endif /* HAVE_IPV6 */
73120 @@ -1187,142 +888,8 @@
73121 return 0;
73124 -/* Utility function comes from iproute2.
73125 - Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
73126 -int
73127 -addattr_l (struct nlmsghdr *n, int maxlen, int type, void *data, int alen)
73129 - int len;
73130 - struct rtattr *rta;
73132 - len = RTA_LENGTH (alen);
73134 - if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen)
73135 - return -1;
73137 - rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len));
73138 - rta->rta_type = type;
73139 - rta->rta_len = len;
73140 - memcpy (RTA_DATA (rta), data, alen);
73141 - n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
73143 - return 0;
73146 -int
73147 -rta_addattr_l (struct rtattr *rta, int maxlen, int type, void *data, int alen)
73149 - int len;
73150 - struct rtattr *subrta;
73152 - len = RTA_LENGTH (alen);
73154 - if (RTA_ALIGN (rta->rta_len) + len > maxlen)
73155 - return -1;
73157 - subrta = (struct rtattr *) (((char *) rta) + RTA_ALIGN (rta->rta_len));
73158 - subrta->rta_type = type;
73159 - subrta->rta_len = len;
73160 - memcpy (RTA_DATA (subrta), data, alen);
73161 - rta->rta_len = NLMSG_ALIGN (rta->rta_len) + len;
73163 - return 0;
73166 -/* Utility function comes from iproute2.
73167 - Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
73168 -int
73169 -addattr32 (struct nlmsghdr *n, int maxlen, int type, int data)
73171 - int len;
73172 - struct rtattr *rta;
73174 - len = RTA_LENGTH (4);
73176 - if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen)
73177 - return -1;
73179 - rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len));
73180 - rta->rta_type = type;
73181 - rta->rta_len = len;
73182 - memcpy (RTA_DATA (rta), &data, 4);
73183 - n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
73185 - return 0;
73188 -static int
73189 -netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h)
73191 - zlog_warn ("netlink_talk: ignoring message type 0x%04x", h->nlmsg_type);
73192 - return 0;
73195 -/* sendmsg() to netlink socket then recvmsg(). */
73196 -int
73197 -netlink_talk (struct nlmsghdr *n, struct nlsock *nl)
73199 - int status;
73200 - struct sockaddr_nl snl;
73201 - struct iovec iov = { (void *) n, n->nlmsg_len };
73202 - struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
73203 - int flags = 0;
73204 - int snb_ret;
73205 - int save_errno;
73207 - memset (&snl, 0, sizeof snl);
73208 - snl.nl_family = AF_NETLINK;
73210 - n->nlmsg_seq = ++nl->seq;
73212 - /* Request an acknowledgement by setting NLM_F_ACK */
73213 - n->nlmsg_flags |= NLM_F_ACK;
73215 - if (IS_ZEBRA_DEBUG_KERNEL)
73216 - zlog_debug ("netlink_talk: %s type %s(%u), seq=%u", nl->name,
73217 - lookup (nlmsg_str, n->nlmsg_type), n->nlmsg_type,
73218 - n->nlmsg_seq);
73220 - /* Send message to netlink interface. */
73221 - if (zserv_privs.change (ZPRIVS_RAISE))
73222 - zlog (NULL, LOG_ERR, "Can't raise privileges");
73223 - status = sendmsg (nl->sock, &msg, 0);
73224 - save_errno = errno;
73225 - if (zserv_privs.change (ZPRIVS_LOWER))
73226 - zlog (NULL, LOG_ERR, "Can't lower privileges");
73228 - if (status < 0)
73230 - zlog (NULL, LOG_ERR, "netlink_talk sendmsg() error: %s",
73231 - safe_strerror (save_errno));
73232 - return -1;
73235 - /*
73236 - * Change socket flags for blocking I/O.
73237 - * This ensures we wait for a reply in netlink_parse_info().
73238 - */
73239 - snb_ret = set_netlink_blocking (nl, &flags);
73240 - if (snb_ret < 0)
73241 - zlog (NULL, LOG_WARNING,
73242 - "%s:%i Warning: Could not set netlink socket to blocking.",
73243 - __FUNCTION__, __LINE__);
73245 - /*
73246 - * Get reply from netlink socket.
73247 - * The reply should either be an acknowlegement or an error.
73248 - */
73249 - status = netlink_parse_info (netlink_talk_filter, nl);
73251 - /* Restore socket flags for nonblocking I/O */
73252 - if (snb_ret == 0)
73253 - set_netlink_nonblocking (nl, &flags);
73255 - return status;
73258 /* Routing table change via netlink interface. */
73259 -int
73260 +static int
73261 netlink_route (int cmd, int family, void *dest, int length, void *gate,
73262 int index, int zebra_flags, int table)
73264 @@ -1389,7 +956,7 @@
73265 snl.nl_family = AF_NETLINK;
73267 /* Talk to netlink socket. */
73268 - ret = netlink_talk (&req.n, &netlink_cmd);
73269 + ret = netlink_talk (&req.n, &netlink_cmd, NULL, 0);
73270 if (ret < 0)
73271 return -1;
73273 @@ -1397,7 +964,7 @@
73276 /* Routing table change via netlink interface. */
73277 -int
73278 +static int
73279 netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
73280 int family)
73282 @@ -1406,6 +973,7 @@
73283 struct nexthop *nexthop = NULL;
73284 int nexthop_num = 0;
73285 int discard;
73286 + int advmss = 0;
73288 struct
73290 @@ -1456,8 +1024,11 @@
73291 if (discard)
73293 if (cmd == RTM_NEWROUTE)
73294 - for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
73295 + for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) {
73296 + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_IGNORE))
73297 + continue;
73298 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
73300 goto skip;
73303 @@ -1466,8 +1037,11 @@
73305 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
73307 + if (nexthop->advmss && nexthop->advmss > advmss)
73308 + advmss = nexthop->advmss;
73310 if ((cmd == RTM_NEWROUTE
73311 + && !CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_IGNORE)
73312 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
73313 || (cmd == RTM_DELROUTE
73314 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
73315 @@ -1487,17 +1061,18 @@
73316 inet_ntoa (p->u.prefix4),
73317 #endif /* HAVE_IPV6 */
73319 - p->prefixlen, nexthop_types_desc[nexthop->rtype]);
73320 + p->prefixlen, nexthop_types_desc(nexthop->rtype));
73323 - if (nexthop->rtype == NEXTHOP_TYPE_IPV4
73324 - || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
73325 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV4))
73327 addattr_l (&req.n, sizeof req, RTA_GATEWAY,
73328 &nexthop->rgate.ipv4, bytelen);
73330 if (nexthop->src.ipv4.s_addr)
73331 addattr_l(&req.n, sizeof req, RTA_PREFSRC,
73332 &nexthop->src.ipv4, bytelen);
73334 if (IS_ZEBRA_DEBUG_KERNEL)
73335 zlog_debug("netlink_route_multipath() (recursive, "
73336 "1 hop): nexthop via %s if %u",
73337 @@ -1505,9 +1080,7 @@
73338 nexthop->rifindex);
73340 #ifdef HAVE_IPV6
73341 - if (nexthop->rtype == NEXTHOP_TYPE_IPV6
73342 - || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX
73343 - || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME)
73344 + else if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV6))
73346 addattr_l (&req.n, sizeof req, RTA_GATEWAY,
73347 &nexthop->rgate.ipv6, bytelen);
73348 @@ -1519,25 +1092,50 @@
73349 nexthop->rifindex);
73351 #endif /* HAVE_IPV6 */
73352 - if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
73353 - || nexthop->rtype == NEXTHOP_TYPE_IFNAME
73354 - || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX
73355 - || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX
73356 - || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME)
73357 + else if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_DROP))
73359 + if (IS_ZEBRA_DEBUG_KERNEL)
73360 + zlog_debug("netlink_route_multipath() (recursive, "
73361 + "1 hop): nexthop DROP(%d)", nexthop->drop);
73364 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IFINDEX) &&
73365 + !(CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV4) ||
73366 + CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV6)))
73368 addattr32 (&req.n, sizeof req, RTA_OIF,
73369 nexthop->rifindex);
73370 - if ((nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX
73371 - || nexthop->rtype == NEXTHOP_TYPE_IFINDEX)
73372 - && nexthop->src.ipv4.s_addr)
73373 - addattr_l (&req.n, sizeof req, RTA_PREFSRC,
73374 - &nexthop->src.ipv4, bytelen);
73376 if (IS_ZEBRA_DEBUG_KERNEL)
73377 zlog_debug("netlink_route_multipath() (recursive, "
73378 "1 hop): nexthop via if %u",
73379 nexthop->rifindex);
73382 +#ifdef HAVE_MPLS
73383 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_MPLS))
73385 +#ifdef LINUX_MPLS
73386 + struct zmpls_out_segment *out;
73387 + char buf[sizeof(struct rtshim) + sizeof(unsigned int)];
73388 + struct rtshim *shim = (struct rtshim*)buf;
73389 + out = mpls_out_segment_find(nexthop->rmpls);
73390 + if (out) {
73391 + strcpy(shim->name, "mpls");
73392 + shim->datalen = sizeof(unsigned int);
73393 + *((unsigned int*)(shim->data)) = out->out_key;
73394 + addattr_l(&req.n, sizeof(req), RTA_SHIM,
73395 + shim, sizeof(buf));
73396 + if (IS_ZEBRA_DEBUG_KERNEL)
73397 + zlog_debug("netlink_route_multipath() (recursive, "
73398 + "1 hop): MPLS info %08x", out->out_key);
73399 + } else {
73400 + zlog_debug("netlink_route_multipath() (multihop): "
73401 + "unable to find NHLFE %d", nexthop->rmpls);
73403 +#endif
73405 +#endif /* HAVE_MPLS */
73407 else
73409 @@ -1552,14 +1150,14 @@
73410 #else
73411 inet_ntoa (p->u.prefix4),
73412 #endif /* HAVE_IPV6 */
73413 - p->prefixlen, nexthop_types_desc[nexthop->type]);
73414 + p->prefixlen, nexthop_types_desc(nexthop->type));
73417 - if (nexthop->type == NEXTHOP_TYPE_IPV4
73418 - || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
73419 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV4))
73421 addattr_l (&req.n, sizeof req, RTA_GATEWAY,
73422 &nexthop->gate.ipv4, bytelen);
73424 if (nexthop->src.ipv4.s_addr)
73425 addattr_l (&req.n, sizeof req, RTA_PREFSRC,
73426 &nexthop->src.ipv4, bytelen);
73427 @@ -1571,9 +1169,7 @@
73428 nexthop->ifindex);
73430 #ifdef HAVE_IPV6
73431 - if (nexthop->type == NEXTHOP_TYPE_IPV6
73432 - || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
73433 - || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
73434 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV6))
73436 addattr_l (&req.n, sizeof req, RTA_GATEWAY,
73437 &nexthop->gate.ipv6, bytelen);
73438 @@ -1585,22 +1181,16 @@
73439 nexthop->ifindex);
73441 #endif /* HAVE_IPV6 */
73442 - if (nexthop->type == NEXTHOP_TYPE_IFINDEX
73443 - || nexthop->type == NEXTHOP_TYPE_IFNAME
73444 - || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
73445 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_DROP))
73447 - addattr32 (&req.n, sizeof req, RTA_OIF, nexthop->ifindex);
73449 - if (nexthop->src.ipv4.s_addr)
73450 - addattr_l (&req.n, sizeof req, RTA_PREFSRC,
73451 - &nexthop->src.ipv4, bytelen);
73453 if (IS_ZEBRA_DEBUG_KERNEL)
73454 zlog_debug("netlink_route_multipath() (single hop): "
73455 - "nexthop via if %u", nexthop->ifindex);
73456 + "nexthop DROP(%d)", nexthop->drop);
73458 - else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX
73459 - || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
73461 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX) &&
73462 + !(CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV4) ||
73463 + CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV6)))
73465 addattr32 (&req.n, sizeof req, RTA_OIF, nexthop->ifindex);
73467 @@ -1608,6 +1198,31 @@
73468 zlog_debug("netlink_route_multipath() (single hop): "
73469 "nexthop via if %u", nexthop->ifindex);
73472 +#ifdef HAVE_MPLS
73473 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_MPLS))
73475 +#ifdef LINUX_MPLS
73476 + struct zmpls_out_segment *out;
73477 + char buf[sizeof(struct rtshim) + sizeof(unsigned int)];
73478 + struct rtshim *shim = (struct rtshim*)buf;
73479 + out = mpls_out_segment_find(nexthop->mpls);
73480 + if (out) {
73481 + strcpy(shim->name, "mpls");
73482 + shim->datalen = sizeof(unsigned int);
73483 + *((unsigned int*)(shim->data)) = out->out_key;
73484 + addattr_l(&req.n, sizeof(req), RTA_SHIM,
73485 + shim, sizeof(buf));
73486 + if (IS_ZEBRA_DEBUG_KERNEL)
73487 + zlog_debug("netlink_route_multipath() (single hop): "
73488 + "MPLS info %08x", out->out_key);
73489 + } else {
73490 + zlog_debug("netlink_route_multipath() (single hop): "
73491 + "unable to find NHLFE %d", nexthop->mpls);
73493 +#endif
73495 +#endif /* HAVE_MPLS */
73498 if (cmd == RTM_NEWROUTE)
73499 @@ -1634,7 +1249,11 @@
73500 nexthop && (MULTIPATH_NUM == 0 || nexthop_num < MULTIPATH_NUM);
73501 nexthop = nexthop->next)
73503 + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_IGNORE))
73504 + continue;
73506 if ((cmd == RTM_NEWROUTE
73507 + && !CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_IGNORE)
73508 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
73509 || (cmd == RTM_DELROUTE
73510 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
73511 @@ -1659,10 +1278,9 @@
73512 #else
73513 inet_ntoa (p->u.prefix4),
73514 #endif /* HAVE_IPV6 */
73515 - p->prefixlen, nexthop_types_desc[nexthop->rtype]);
73516 + p->prefixlen, nexthop_types_desc(nexthop->type));
73518 - if (nexthop->rtype == NEXTHOP_TYPE_IPV4
73519 - || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
73520 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV4))
73522 rta_addattr_l (rta, 4096, RTA_GATEWAY,
73523 &nexthop->rgate.ipv4, bytelen);
73524 @@ -1678,9 +1296,7 @@
73525 nexthop->rifindex);
73527 #ifdef HAVE_IPV6
73528 - if (nexthop->rtype == NEXTHOP_TYPE_IPV6
73529 - || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME
73530 - || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX)
73531 + else if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV6))
73533 rta_addattr_l (rta, 4096, RTA_GATEWAY,
73534 &nexthop->rgate.ipv6, bytelen);
73535 @@ -1692,22 +1308,16 @@
73536 nexthop->rifindex);
73538 #endif /* HAVE_IPV6 */
73539 - /* ifindex */
73540 - if (nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX
73541 - || nexthop->rtype == NEXTHOP_TYPE_IFINDEX
73542 - || nexthop->rtype == NEXTHOP_TYPE_IFNAME)
73543 + else if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_DROP))
73545 - rtnh->rtnh_ifindex = nexthop->rifindex;
73546 - if (nexthop->src.ipv4.s_addr)
73547 - src = &nexthop->src;
73549 - if (IS_ZEBRA_DEBUG_KERNEL)
73550 zlog_debug("netlink_route_multipath() (recursive, "
73551 - "multihop): nexthop via if %u",
73552 - nexthop->rifindex);
73553 + "multihop): nexthop DROP %d", nexthop->drop);
73555 - else if (nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX
73556 - || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME)
73558 + /* ifindex */
73559 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IFINDEX) &&
73560 + !(CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV4) ||
73561 + CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV6)))
73563 rtnh->rtnh_ifindex = nexthop->rifindex;
73565 @@ -1720,6 +1330,32 @@
73567 rtnh->rtnh_ifindex = 0;
73570 +#ifdef HAVE_MPLS
73571 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_MPLS))
73573 +#ifdef LINUX_MPLS
73574 + struct zmpls_out_segment *out;
73575 + char buf[sizeof(struct rtshim) + sizeof(unsigned int)];
73576 + struct rtshim *shim = (struct rtshim*)buf;
73577 + out = mpls_out_segment_find(nexthop->rmpls);
73578 + if (out) {
73579 + strcpy(shim->name, "mpls");
73580 + shim->datalen = sizeof(unsigned int);
73581 + *((unsigned int*)(shim->data)) = out->out_key;
73582 + addattr_l(&req.n, sizeof(req), RTA_SHIM,
73583 + shim, sizeof(buf));
73584 + if (IS_ZEBRA_DEBUG_KERNEL)
73585 + zlog_debug("netlink_route_multipath() (recursive "
73586 + "multihop): MPLS info %08x", out->out_key);
73587 + } else {
73588 + zlog_debug("netlink_route_multipath() (recursive "
73589 + "multihop): unable to find NHLFE %d",
73590 + nexthop->rmpls);
73592 +#endif
73594 +#endif /* HAVE_MPLS */
73596 else
73598 @@ -1733,10 +1369,9 @@
73599 #else
73600 inet_ntoa (p->u.prefix4),
73601 #endif /* HAVE_IPV6 */
73602 - p->prefixlen, nexthop_types_desc[nexthop->type]);
73603 + p->prefixlen, nexthop_types_desc(nexthop->type));
73605 - if (nexthop->type == NEXTHOP_TYPE_IPV4
73606 - || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
73607 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV4))
73609 rta_addattr_l (rta, 4096, RTA_GATEWAY,
73610 &nexthop->gate.ipv4, bytelen);
73611 @@ -1752,9 +1387,7 @@
73612 nexthop->ifindex);
73614 #ifdef HAVE_IPV6
73615 - if (nexthop->type == NEXTHOP_TYPE_IPV6
73616 - || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
73617 - || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
73618 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV6))
73620 rta_addattr_l (rta, 4096, RTA_GATEWAY,
73621 &nexthop->gate.ipv6, bytelen);
73622 @@ -1766,20 +1399,16 @@
73623 nexthop->ifindex);
73625 #endif /* HAVE_IPV6 */
73626 - /* ifindex */
73627 - if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
73628 - || nexthop->type == NEXTHOP_TYPE_IFINDEX
73629 - || nexthop->type == NEXTHOP_TYPE_IFNAME)
73631 - rtnh->rtnh_ifindex = nexthop->ifindex;
73632 - if (nexthop->src.ipv4.s_addr)
73633 - src = &nexthop->src;
73634 - if (IS_ZEBRA_DEBUG_KERNEL)
73635 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_DROP))
73637 zlog_debug("netlink_route_multipath() (multihop): "
73638 - "nexthop via if %u", nexthop->ifindex);
73639 + "nexthop DROP %d", nexthop->drop);
73641 - else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
73642 - || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
73644 + /* ifindex */
73645 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX) &&
73646 + !(CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV4) ||
73647 + CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV6)))
73649 rtnh->rtnh_ifindex = nexthop->ifindex;
73651 @@ -1791,6 +1420,31 @@
73653 rtnh->rtnh_ifindex = 0;
73656 +#ifdef HAVE_MPLS
73657 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_MPLS))
73659 +#ifdef LINUX_MPLS
73660 + struct zmpls_out_segment *out;
73661 + char buf[sizeof(struct rtshim) + sizeof(unsigned int)];
73662 + struct rtshim *shim = (struct rtshim*)buf;
73663 + out = mpls_out_segment_find(nexthop->mpls);
73664 + if (out) {
73665 + strcpy(shim->name, "mpls");
73666 + shim->datalen = sizeof(unsigned int);
73667 + *((unsigned int*)(shim->data)) = out->out_key;
73668 + addattr_l(&req.n, sizeof(req), RTA_SHIM,
73669 + shim, sizeof(buf));
73670 + if (IS_ZEBRA_DEBUG_KERNEL)
73671 + zlog_debug("netlink_route_multipath() (multihop): "
73672 + "MPLS info %08x", out->out_key);
73673 + } else {
73674 + zlog_debug("netlink_route_multipath() (multihop): "
73675 + "unable to find NHLFE %d", nexthop->mpls);
73677 +#endif
73679 +#endif /* HAVE_MPLS */
73681 rtnh = RTNH_NEXT (rtnh);
73683 @@ -1806,6 +1460,20 @@
73684 RTA_PAYLOAD (rta));
73687 + if (advmss)
73689 + char buf[1024];
73690 + struct rtattr *rta = (void *) buf;
73691 + unsigned int mss = advmss;
73693 + rta->rta_type = RTA_METRICS;
73694 + rta->rta_len = RTA_LENGTH (0);
73696 + rta_addattr_l (rta, sizeof (buf), RTAX_ADVMSS, &mss, sizeof (mss));
73697 + addattr_l(&req.n, sizeof (buf), RTA_METRICS, RTA_DATA (rta),
73698 + RTA_PAYLOAD (rta));
73701 /* If there is no useful nexthop then return. */
73702 if (nexthop_num == 0)
73704 @@ -1821,7 +1489,7 @@
73705 snl.nl_family = AF_NETLINK;
73707 /* Talk to netlink socket. */
73708 - return netlink_talk (&req.n, &netlink_cmd);
73709 + return netlink_talk (&req.n, &netlink_cmd, NULL, 0);
73713 @@ -1860,7 +1528,7 @@
73714 #endif /* HAVE_IPV6 */
73716 /* Interface address modification. */
73717 -int
73718 +static int
73719 netlink_address (int cmd, int family, struct interface *ifp,
73720 struct connected *ifc)
73722 @@ -1897,6 +1565,12 @@
73723 addattr_l (&req.n, sizeof req, IFA_BROADCAST, &p->u.prefix,
73724 bytelen);
73726 + else if (if_is_pointopoint (ifp) && ifc->destination)
73728 + p = ifc->destination;
73729 + addattr_l (&req.n, sizeof req, IFA_ADDRESS, &p->u.prefix,
73730 + bytelen);
73734 if (CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
73735 @@ -1906,7 +1580,7 @@
73736 addattr_l (&req.n, sizeof req, IFA_LABEL, ifc->label,
73737 strlen (ifc->label) + 1);
73739 - return netlink_talk (&req.n, &netlink_cmd);
73740 + return netlink_talk (&req.n, &netlink_cmd, NULL, 0);
73744 @@ -1925,14 +1599,14 @@
73745 extern struct thread_master *master;
73747 /* Kernel route reflection. */
73748 -int
73749 +static int
73750 kernel_read (struct thread *thread)
73752 int ret;
73753 int sock;
73755 sock = THREAD_FD (thread);
73756 - ret = netlink_parse_info (netlink_information_fetch, &netlink);
73757 + ret = netlink_parse_info (netlink_information_fetch, &netlink, NULL, 0);
73758 thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock);
73760 return 0;
73761 @@ -1999,8 +1673,8 @@
73762 #ifdef HAVE_IPV6
73763 groups |= RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR;
73764 #endif /* HAVE_IPV6 */
73765 - netlink_socket (&netlink, groups);
73766 - netlink_socket (&netlink_cmd, 0);
73767 + netlink_socket (&netlink, NETLINK_ROUTE, groups);
73768 + netlink_socket (&netlink_cmd, NETLINK_ROUTE, 0);
73770 /* Register kernel socket. */
73771 if (netlink.sock > 0)
73772 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/rt_netlink.h quagga-mpls/zebra/rt_netlink.h
73773 --- quagga/zebra/rt_netlink.h 1969-12-31 18:00:00.000000000 -0600
73774 +++ quagga-mpls/zebra/rt_netlink.h 2006-08-09 22:03:17.000000000 -0500
73775 @@ -0,0 +1,7 @@
73776 +#ifndef ZEBRA_RT_NETLINK_H
73777 +#define ZEBRA_RT_NETLINK_H
73779 +extern int netlink_route_read ();
73780 +extern int interface_lookup_netlink ();
73782 +#endif
73783 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/rtread_getmsg.c quagga-mpls/zebra/rtread_getmsg.c
73784 --- quagga/zebra/rtread_getmsg.c 2007-05-02 10:28:33.000000000 -0500
73785 +++ quagga-mpls/zebra/rtread_getmsg.c 2008-02-19 22:55:41.000000000 -0600
73786 @@ -71,7 +71,8 @@
73788 struct prefix_ipv4 prefix;
73789 struct in_addr tmpaddr, gateway;
73790 - u_char zebra_flags = 0;
73791 + u_short zebra_flags = 0;
73792 + struct zapi_nexthop nh;
73794 if (routeEntry->ipRouteInfo.re_ire_type & IRE_CACHETABLE)
73795 return;
73796 @@ -79,6 +80,8 @@
73797 if (routeEntry->ipRouteInfo.re_ire_type & IRE_HOST_REDIRECT)
73798 zebra_flags |= ZEBRA_FLAG_SELFROUTE;
73800 + memset(&nh, 0, sizeof(struct zapi_nexthop));
73802 prefix.family = AF_INET;
73804 tmpaddr.s_addr = routeEntry->ipRouteDest;
73805 @@ -88,9 +91,11 @@
73806 prefix.prefixlen = ip_masklen (tmpaddr);
73808 gateway.s_addr = routeEntry->ipRouteNextHop;
73809 + nh.gw.ipv4 = gateway;
73810 + SET_FLAG(nh.type, ZEBRA_NEXTHOP_IPV4);
73812 - rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &prefix,
73813 - &gateway, NULL, 0, 0, 0, 0);
73814 + rib_add_route (ZEBRA_ROUTE_KERNEL, zebra_flags,
73815 + (struct prefix*)&prefix, &nh, 0, 0, 0);
73818 void
73819 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/rtread_netlink.c quagga-mpls/zebra/rtread_netlink.c
73820 --- quagga/zebra/rtread_netlink.c 2002-12-13 14:15:30.000000000 -0600
73821 +++ quagga-mpls/zebra/rtread_netlink.c 2006-08-09 22:03:13.000000000 -0500
73822 @@ -22,8 +22,12 @@
73824 #include <zebra.h>
73826 -/* Extern from rt_netlink.c */
73827 -void netlink_route_read ();
73828 +#include "if.h"
73829 +#include "prefix.h"
73830 +#include "rib.h"
73832 +#include "zebra/zserv.h"
73833 +#include "zebra/rt_netlink.h"
73835 void route_read ()
73837 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/rtread_proc.c quagga-mpls/zebra/rtread_proc.c
73838 --- quagga/zebra/rtread_proc.c 2007-05-02 10:28:33.000000000 -0500
73839 +++ quagga-mpls/zebra/rtread_proc.c 2008-02-19 22:55:41.000000000 -0600
73840 @@ -72,7 +72,8 @@
73841 struct prefix_ipv4 p;
73842 struct in_addr tmpmask;
73843 struct in_addr gateway;
73844 - u_char zebra_flags = 0;
73845 + struct zapi_nexthop nh;
73846 + u_short zebra_flags = 0;
73848 n = sscanf (buf, "%s %s %s %x %d %d %d %s %d %d %d",
73849 iface, dest, gate, &flags, &refcnt, &use, &metric,
73850 @@ -87,6 +88,8 @@
73851 if (! (flags & RTF_GATEWAY))
73852 continue;
73854 + memset(&nh, 0, sizeof(struct zapi_nexthop));
73856 if (flags & RTF_DYNAMIC)
73857 zebra_flags |= ZEBRA_FLAG_SELFROUTE;
73859 @@ -96,7 +99,11 @@
73860 p.prefixlen = ip_masklen (tmpmask);
73861 sscanf (gate, "%lX", (unsigned long *)&gateway);
73863 - rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gateway, NULL, 0, 0, 0, 0);
73864 + SET_FLAG(nh.type, ZEBRA_NEXTHOP_IPV4);
73865 + nh.gw.ipv4 = gateway;
73867 + rib_add_route (ZEBRA_ROUTE_KERNEL, zebra_flags, (struct prefix*)&p,
73868 + &nh, 0, 0, 0);
73871 fclose (fp);
73872 @@ -129,7 +136,8 @@
73873 int metric, use, refcnt, flags;
73874 struct prefix_ipv6 p;
73875 struct in6_addr gateway;
73876 - u_char zebra_flags = 0;
73877 + u_short zebra_flags = 0;
73878 + struct zapi_nexthop nh;
73880 /* Linux 2.1.x write this information at net/ipv6/route.c
73881 rt6_info_node () */
73882 @@ -148,6 +156,8 @@
73883 if (! (flags & RTF_GATEWAY))
73884 continue;
73886 + memset(&nh, 0, sizeof(struct zapi_nexthop));
73888 if (flags & RTF_DYNAMIC)
73889 zebra_flags |= ZEBRA_FLAG_SELFROUTE;
73891 @@ -156,8 +166,11 @@
73892 str2in6_addr (gate, &gateway);
73893 p.prefixlen = dest_plen;
73895 - rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gateway, 0, 0,
73896 - metric, 0);
73897 + SET_FLAG(nh.type, ZEBRA_NEXTHOP_IPV4);
73898 + nh.gw.ipv4 = gateway;
73900 + rib_add_route (ZEBRA_ROUTE_KERNEL, zebra_flags, (struct prefix*)&p,
73901 + &nh, 0, metric, 0);
73904 fclose (fp);
73905 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/rt_socket.c quagga-mpls/zebra/rt_socket.c
73906 --- quagga/zebra/rt_socket.c 2008-09-04 20:37:37.000000000 -0500
73907 +++ quagga-mpls/zebra/rt_socket.c 2008-09-07 20:23:37.000000000 -0500
73908 @@ -114,37 +114,46 @@
73910 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
73912 - if (nexthop->rtype == NEXTHOP_TYPE_IPV4 ||
73913 - nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
73914 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV4))
73916 sin_gate.sin_addr = nexthop->rgate.ipv4;
73917 gate = 1;
73919 - if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
73920 - || nexthop->rtype == NEXTHOP_TYPE_IFNAME
73921 - || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
73922 + else if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV6))
73923 + assert (0);
73924 + else if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_DROP))
73926 + struct in_addr loopback;
73927 + loopback.s_addr = htonl (INADDR_LOOPBACK);
73928 + sin_gate.sin_addr = loopback;
73929 + gate = 1;
73932 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IFINDEX))
73933 ifindex = nexthop->rifindex;
73935 else
73937 - if (nexthop->type == NEXTHOP_TYPE_IPV4 ||
73938 - nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
73939 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV4))
73941 sin_gate.sin_addr = nexthop->gate.ipv4;
73942 gate = 1;
73944 - if (nexthop->type == NEXTHOP_TYPE_IFINDEX
73945 - || nexthop->type == NEXTHOP_TYPE_IFNAME
73946 - || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
73947 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV6))
73948 + assert (0);
73949 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_DROP))
73951 + struct in_addr loopback;
73952 + loopback.s_addr = htonl (INADDR_LOOPBACK);
73953 + sin_gate.sin_addr = loopback;
73954 + gate = 1;
73957 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX))
73958 ifindex = nexthop->ifindex;
73959 - if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE)
73961 - struct in_addr loopback;
73962 - loopback.s_addr = htonl (INADDR_LOOPBACK);
73963 - sin_gate.sin_addr = loopback;
73964 - gate = 1;
73968 + if (cmd == RTM_ADD)
73969 + SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
73971 if (gate && p->prefixlen == 32)
73972 mask = NULL;
73973 @@ -390,32 +399,28 @@
73975 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
73977 - if (nexthop->rtype == NEXTHOP_TYPE_IPV6
73978 - || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME
73979 - || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX)
73980 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV6))
73982 sin_gate.sin6_addr = nexthop->rgate.ipv6;
73983 gate = 1;
73985 - if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
73986 - || nexthop->rtype == NEXTHOP_TYPE_IFNAME
73987 - || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME
73988 - || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX)
73989 + else if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV4))
73990 + assert (0);
73992 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IFINDEX))
73993 ifindex = nexthop->rifindex;
73995 else
73997 - if (nexthop->type == NEXTHOP_TYPE_IPV6
73998 - || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
73999 - || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
74000 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV6))
74002 sin_gate.sin6_addr = nexthop->gate.ipv6;
74003 gate = 1;
74005 - if (nexthop->type == NEXTHOP_TYPE_IFINDEX
74006 - || nexthop->type == NEXTHOP_TYPE_IFNAME
74007 - || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
74008 - || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
74009 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV4))
74010 + assert (0);
74012 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX))
74013 ifindex = nexthop->ifindex;
74016 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/zebra_rib.c quagga-mpls/zebra/zebra_rib.c
74017 --- quagga/zebra/zebra_rib.c 2008-09-04 20:37:37.000000000 -0500
74018 +++ quagga-mpls/zebra/zebra_rib.c 2008-09-07 20:23:37.000000000 -0500
74019 @@ -72,6 +72,11 @@
74020 /* Vector for routing table. */
74021 vector vrf_vector;
74023 +#ifdef HAVE_IPV6
74024 +static int
74025 +rib_bogus_ipv6 (int, struct prefix_ipv6*, struct in6_addr*, unsigned int, int);
74026 +#endif
74028 /* Allocate new VRF. */
74029 static struct vrf *
74030 vrf_alloc (const char *name)
74031 @@ -165,173 +170,432 @@
74032 return vrf->stable[afi][safi];
74035 -/* Add nexthop to the end of the list. */
74036 -static void
74037 -nexthop_add (struct rib *rib, struct nexthop *nexthop)
74038 +static int
74039 +zapi_nexthop_str(struct zapi_nexthop *nh, char *buf, int size)
74041 - struct nexthop *last;
74042 + struct interface *ifp = NULL;
74043 + char buf1[BUFSIZ];
74044 + char *ptr = buf;
74045 + int len = 0;
74047 - for (last = rib->nexthop; last && last->next; last = last->next)
74049 - if (last)
74050 - last->next = nexthop;
74051 - else
74052 - rib->nexthop = nexthop;
74053 - nexthop->prev = last;
74054 + if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_DROP))
74056 + switch (nh->gw.drop)
74058 + case ZEBRA_DROP_NULL:
74059 + len = snprintf(buf, size, " Null0");
74060 + break;
74061 + case ZEBRA_DROP_REJECT:
74062 + len = snprintf(buf, size, " reject");
74063 + break;
74064 + case ZEBRA_DROP_BLACKHOLE:
74065 + len = snprintf(buf, size, " blackhole");
74066 + break;
74067 + default:
74068 + assert(0);
74072 - rib->nexthop_num++;
74074 + if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_IPV4))
74076 + inet_ntop (AF_INET, &nh->gw.ipv4, buf1, BUFSIZ),
74077 + len += snprintf(ptr, size, " via %s", buf1);
74078 + ptr = &buf[len];
74080 +#ifdef HAVE_IPV6
74081 + else if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_IPV6))
74083 + inet_ntop (AF_INET6, &nh->gw.ipv6, buf1, BUFSIZ),
74084 + len += snprintf(ptr, size, " via %s", buf1);
74085 + ptr = &buf[len];
74087 +#endif
74089 -/* Delete specified nexthop from the list. */
74090 -static void
74091 -nexthop_delete (struct rib *rib, struct nexthop *nexthop)
74093 - if (nexthop->next)
74094 - nexthop->next->prev = nexthop->prev;
74095 - if (nexthop->prev)
74096 - nexthop->prev->next = nexthop->next;
74097 - else
74098 - rib->nexthop = nexthop->next;
74099 - rib->nexthop_num--;
74101 + if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_IFINDEX))
74103 + ifp = if_lookup_by_index (nh->intf.index);
74105 + else if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_IFNAME))
74107 + ifp = if_lookup_by_name (nh->intf.name);
74110 -/* Free nexthop. */
74111 -static void
74112 -nexthop_free (struct nexthop *nexthop)
74114 - if (nexthop->ifname)
74115 - XFREE (0, nexthop->ifname);
74116 - XFREE (MTYPE_NEXTHOP, nexthop);
74117 + if (ifp)
74119 + len += snprintf(ptr, size - len, " intf %s(%d)", ifp->name, ifp->ifindex);
74120 + ptr = &buf[len];
74122 +#ifdef HAVE_MPLS
74123 + if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_MPLS))
74125 + struct zmpls_out_segment *out;
74126 + out = mpls_out_segment_find(&nh->mpls);
74127 + if (out)
74129 + len += snprintf(ptr, size - len, " mpls 0x%08x", nh->mpls);
74130 + ptr = &buf[len];
74133 +#endif
74134 + return len;
74137 -struct nexthop *
74138 -nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
74139 +static int
74140 +nexthop_str(struct nexthop *nh, char *buf, int size)
74142 - struct nexthop *nexthop;
74143 + struct interface *ifp = NULL;
74144 + char buf1[BUFSIZ];
74145 + char *ptr = buf;
74146 + int len = 0;
74148 - nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
74149 - memset (nexthop, 0, sizeof (struct nexthop));
74150 - nexthop->type = NEXTHOP_TYPE_IFINDEX;
74151 - nexthop->ifindex = ifindex;
74152 + if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_DROP))
74154 + switch (nh->drop)
74156 + case ZEBRA_DROP_NULL:
74157 + len = snprintf(buf, size, " Null0");
74158 + break;
74159 + case ZEBRA_DROP_REJECT:
74160 + len = snprintf(buf, size, " reject");
74161 + break;
74162 + case ZEBRA_DROP_BLACKHOLE:
74163 + len = snprintf(buf, size, " blackhole");
74164 + break;
74165 + default:
74166 + assert(0);
74170 - nexthop_add (rib, nexthop);
74171 + if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_IPV4))
74173 + inet_ntop (AF_INET, &nh->gate.ipv4, buf1, BUFSIZ),
74174 + len += snprintf(ptr, size, " via %s", buf1);
74175 + ptr = &buf[len];
74177 +#ifdef HAVE_IPV6
74178 + else if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_IPV6))
74180 + inet_ntop (AF_INET6, &nh->gate.ipv6, buf1, BUFSIZ),
74181 + len += snprintf(ptr, size, " via %s", buf1);
74182 + ptr = &buf[len];
74184 +#endif
74186 - return nexthop;
74187 + if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_IFINDEX))
74189 + ifp = if_lookup_by_index (nh->ifindex);
74191 + else if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_IFNAME))
74193 + ifp = if_lookup_by_name (nh->ifname);
74196 + if (ifp)
74198 + len += snprintf(ptr, size - len, " intf %s(%d)", ifp->name, ifp->ifindex);
74199 + ptr = &buf[len];
74201 +#ifdef HAVE_MPLS
74202 + if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_MPLS))
74204 + struct zmpls_out_segment *out;
74205 + out = mpls_out_segment_find(&nh->mpls);
74206 + if (out)
74208 + len += snprintf(ptr, size - len, " mpls 0x%08x", nh->mpls);
74209 + ptr = &buf[len];
74212 +#endif
74213 + return len;
74216 -struct nexthop *
74217 -nexthop_ifname_add (struct rib *rib, char *ifname)
74218 +static int
74219 +zapi_nexthop_match_nexthop(struct zapi_nexthop *znh, struct nexthop *nh, int mask)
74221 - struct nexthop *nexthop;
74223 - nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
74224 - memset (nexthop, 0, sizeof (struct nexthop));
74225 - nexthop->type = NEXTHOP_TYPE_IFNAME;
74226 - nexthop->ifname = XSTRDUP (0, ifname);
74227 + int either = (nh->type | znh->type) & mask;
74228 + int both = (nh->type & znh->type) & mask;
74229 + int try = 0;
74230 + int match = 0;
74231 + int v4_gate_match = 0;
74233 + try++;
74234 + if (nh->advmss == znh->advmss)
74235 + match++;
74237 + if (CHECK_FLAG(either, ZEBRA_NEXTHOP_DROP))
74239 + try++;
74240 + if (CHECK_FLAG(both, ZEBRA_NEXTHOP_DROP) &&
74241 + nh->drop == znh->gw.drop)
74242 + match++;
74244 + else if (CHECK_FLAG(either, ZEBRA_NEXTHOP_IPV4))
74246 + try++;
74247 + if (CHECK_FLAG(both, ZEBRA_NEXTHOP_IPV4) &&
74248 + (IPV4_ADDR_SAME (&nh->gate.ipv4, &znh->gw.ipv4) ||
74249 + IPV4_ADDR_SAME (&nh->rgate.ipv4, &znh->gw.ipv4)))
74251 + match++;
74252 + v4_gate_match = 1;
74255 +#ifdef HAVE_IPV6
74256 + else if (CHECK_FLAG(either, ZEBRA_NEXTHOP_IPV6))
74258 + try++;
74259 + if (CHECK_FLAG(both, ZEBRA_NEXTHOP_IPV6) &&
74260 + (IPV6_ADDR_SAME (&nh->gate.ipv6, &znh->gw.ipv6) ||
74261 + IPV6_ADDR_SAME (&nh->rgate.ipv6, &znh->gw.ipv6)))
74262 + match++;
74264 +#endif
74266 - nexthop_add (rib, nexthop);
74267 + if (CHECK_FLAG(either, ZEBRA_NEXTHOP_IFINDEX))
74269 + if (!v4_gate_match)
74271 + try++;
74272 + if (CHECK_FLAG (both, ZEBRA_NEXTHOP_IFINDEX) &&
74273 + (nh->ifindex == znh->intf.index))
74274 + match++;
74276 + else if (CHECK_FLAG (both, ZEBRA_NEXTHOP_IFINDEX))
74278 + try++;
74279 + if (nh->ifindex == znh->intf.index)
74280 + match++;
74283 + else if (CHECK_FLAG(either, ZEBRA_NEXTHOP_IFNAME))
74285 + try++;
74286 + if (CHECK_FLAG(both, ZEBRA_NEXTHOP_IFNAME) &&
74287 + (!strncmp(nh->ifname, znh->intf.name, IFNAMSIZ)))
74288 + match++;
74291 - return nexthop;
74292 + if (CHECK_FLAG(either, ZEBRA_NEXTHOP_SRC_IPV4))
74294 + try++;
74295 + if (CHECK_FLAG(both, ZEBRA_NEXTHOP_SRC_IPV4) &&
74296 + IPV4_ADDR_SAME (&nh->src.ipv4, &znh->src.ipv4))
74297 + match++;
74299 +#ifdef HAVE_IPV6
74300 + else if (CHECK_FLAG(either, ZEBRA_NEXTHOP_SRC_IPV6))
74302 + try++;
74303 + if (CHECK_FLAG(both, ZEBRA_NEXTHOP_SRC_IPV6) &&
74304 + IPV6_ADDR_SAME (&nh->src.ipv6, &znh->src.ipv6))
74305 + match++;
74307 +#endif
74308 +#ifdef HAVE_MPLS
74309 + if (CHECK_FLAG(either, ZEBRA_NEXTHOP_MPLS))
74311 + try++;
74312 + if (CHECK_FLAG(both, ZEBRA_NEXTHOP_MPLS) &&
74313 + nh->mpls == mpls_out_segment_find_index_by_nexthop(znh))
74314 + match++;
74316 +#endif
74317 + return (try && try == match) ? 1 : 0;
74320 -struct nexthop *
74321 -nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
74322 +static int
74323 +zapi_nexthop_match_static_route(u_char distance, struct zapi_nexthop *znh,
74324 + struct static_route *si)
74326 - struct nexthop *nexthop;
74327 + int try = 0;
74328 + int match = 0;
74330 - nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
74331 - memset (nexthop, 0, sizeof (struct nexthop));
74332 - nexthop->type = NEXTHOP_TYPE_IPV4;
74333 - nexthop->gate.ipv4 = *ipv4;
74334 - if (src)
74335 - nexthop->src.ipv4 = *src;
74336 + try++;
74337 + if (distance == si->distance)
74338 + match++;
74340 - nexthop_add (rib, nexthop);
74341 + try++;
74342 + if (zapi_nexthop_match(znh, &si->nh, ZEBRA_NEXTHOP_ALL))
74343 + match++;
74345 - return nexthop;
74346 + return (try && try == match) ? 1 : 0;
74349 -static struct nexthop *
74350 -nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
74351 - struct in_addr *src, unsigned int ifindex)
74352 +void
74353 +zapi_nexthop2nexthop(struct zapi_nexthop* znh, struct nexthop *nh)
74355 - struct nexthop *nexthop;
74357 - nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
74358 - memset (nexthop, 0, sizeof (struct nexthop));
74359 - nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
74360 - nexthop->gate.ipv4 = *ipv4;
74361 - if (src)
74362 - nexthop->src.ipv4 = *src;
74363 - nexthop->ifindex = ifindex;
74364 + nh->type = znh->type;
74365 + nh->advmss = znh->advmss;
74367 - nexthop_add (rib, nexthop);
74368 + if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_DROP))
74369 + nh->drop = znh->gw.drop;
74370 + else if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_SRC_IPV4))
74371 + nh->src.ipv4 = znh->src.ipv4;
74372 +#ifdef HAVE_IPV6
74373 + else if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_SRC_IPV6))
74374 + nh->src.ipv6 = znh->src.ipv6;
74375 +#endif
74377 - return nexthop;
74378 + if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_IPV4))
74379 + nh->gate.ipv4 = znh->gw.ipv4;
74380 +#ifdef HAVE_IPV6
74381 + else if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_IPV6))
74382 + nh->gate.ipv6 = znh->gw.ipv6;
74383 +#endif
74385 + if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_IFINDEX))
74386 + nh->ifindex = znh->intf.index;
74387 + else if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_IFNAME))
74388 + nh->ifname = XSTRDUP (0, znh->intf.name);
74389 +#ifdef HAVE_MPLS
74390 + if (CHECK_FLAG(nh->type, ZEBRA_NEXTHOP_MPLS))
74391 + nh->mpls = mpls_out_segment_find_index_by_nexthop(znh);
74392 +#endif
74395 -#ifdef HAVE_IPV6
74396 -struct nexthop *
74397 -nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
74398 +static int
74399 +nexthop_match(struct nexthop *znh, struct nexthop *nh, int mask)
74401 - struct nexthop *nexthop;
74403 - nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
74404 - memset (nexthop, 0, sizeof (struct nexthop));
74405 - nexthop->type = NEXTHOP_TYPE_IPV6;
74406 - nexthop->gate.ipv6 = *ipv6;
74407 + int either = (nh->type | znh->type) & mask;
74408 + int both = (nh->type & znh->type) & mask;
74409 + int try = 0;
74410 + int match = 0;
74411 + int v4_gate_match = 0;
74413 + try++;
74414 + if (nh->advmss == znh->advmss)
74415 + match++;
74417 + if (CHECK_FLAG(either, ZEBRA_NEXTHOP_DROP))
74419 + try++;
74420 + if (CHECK_FLAG(both, ZEBRA_NEXTHOP_DROP) &&
74421 + nh->drop == znh->drop)
74422 + match++;
74424 + else if (CHECK_FLAG(either, ZEBRA_NEXTHOP_IPV4))
74426 + try++;
74427 + if (CHECK_FLAG(both, ZEBRA_NEXTHOP_IPV4) &&
74428 + (IPV4_ADDR_SAME (&nh->gate.ipv4, &znh->gate.ipv4) ||
74429 + IPV4_ADDR_SAME (&nh->rgate.ipv4, &znh->rgate.ipv4)))
74431 + match++;
74432 + v4_gate_match = 1;
74435 +#ifdef HAVE_IPV6
74436 + else if (CHECK_FLAG(either, ZEBRA_NEXTHOP_IPV6))
74438 + try++;
74439 + if (CHECK_FLAG(both, ZEBRA_NEXTHOP_IPV6) &&
74440 + (IPV6_ADDR_SAME (&nh->gate.ipv6, &znh->gate.ipv6) ||
74441 + IPV6_ADDR_SAME (&nh->rgate.ipv6, &znh->rgate.ipv6)))
74442 + match++;
74444 +#endif
74446 - nexthop_add (rib, nexthop);
74447 + if (CHECK_FLAG(either, ZEBRA_NEXTHOP_IFINDEX))
74449 + if (!v4_gate_match)
74451 + try++;
74452 + if (CHECK_FLAG (both, ZEBRA_NEXTHOP_IFINDEX) &&
74453 + (nh->ifindex == znh->ifindex))
74454 + match++;
74456 + else if (CHECK_FLAG (both, ZEBRA_NEXTHOP_IFINDEX))
74458 + try++;
74459 + if (nh->ifindex == znh->ifindex)
74460 + match++;
74463 + else if (CHECK_FLAG(either, ZEBRA_NEXTHOP_IFNAME))
74465 + try++;
74466 + if (CHECK_FLAG(both, ZEBRA_NEXTHOP_IFNAME) &&
74467 + (!strncmp(nh->ifname, znh->ifname, IFNAMSIZ)))
74468 + match++;
74471 - return nexthop;
74472 + if (CHECK_FLAG(either, ZEBRA_NEXTHOP_SRC_IPV4))
74474 + try++;
74475 + if (CHECK_FLAG(both, ZEBRA_NEXTHOP_SRC_IPV4) &&
74476 + IPV4_ADDR_SAME (&nh->src.ipv4, &znh->src.ipv4))
74477 + match++;
74479 +#ifdef HAVE_IPV6
74480 + else if (CHECK_FLAG(either, ZEBRA_NEXTHOP_SRC_IPV6))
74482 + try++;
74483 + if (CHECK_FLAG(both, ZEBRA_NEXTHOP_SRC_IPV6) &&
74484 + IPV6_ADDR_SAME (&nh->src.ipv6, &znh->src.ipv6))
74485 + match++;
74487 +#endif
74488 +#ifdef HAVE_MPLS
74489 + if (CHECK_FLAG(either, ZEBRA_NEXTHOP_MPLS))
74491 + try++;
74492 + if (CHECK_FLAG(both, ZEBRA_NEXTHOP_MPLS) &&
74493 + nh->mpls == znh->mpls)
74494 + match++;
74496 +#endif
74497 + return (try && try == match) ? 1 : 0;
74500 -static struct nexthop *
74501 -nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
74502 - char *ifname)
74503 +/* Add nexthop to the end of the list. */
74504 +static void
74505 +nexthop_add (struct rib *rib, struct nexthop *nexthop)
74507 - struct nexthop *nexthop;
74509 - nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
74510 - memset (nexthop, 0, sizeof (struct nexthop));
74511 - nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
74512 - nexthop->gate.ipv6 = *ipv6;
74513 - nexthop->ifname = XSTRDUP (0, ifname);
74514 + struct nexthop *last;
74516 - nexthop_add (rib, nexthop);
74517 + for (last = rib->nexthop; last && last->next; last = last->next)
74519 + if (last)
74520 + last->next = nexthop;
74521 + else
74522 + rib->nexthop = nexthop;
74523 + nexthop->prev = last;
74525 - return nexthop;
74526 + rib->nexthop_num++;
74529 -static struct nexthop *
74530 -nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
74531 - unsigned int ifindex)
74532 +/* Delete specified nexthop from the list. */
74533 +void
74534 +nexthop_delete (struct rib *rib, struct nexthop *nexthop)
74536 - struct nexthop *nexthop;
74538 - nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
74539 - memset (nexthop, 0, sizeof (struct nexthop));
74540 - nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
74541 - nexthop->gate.ipv6 = *ipv6;
74542 - nexthop->ifindex = ifindex;
74544 - nexthop_add (rib, nexthop);
74545 + if (nexthop->next)
74546 + nexthop->next->prev = nexthop->prev;
74547 + if (nexthop->prev)
74548 + nexthop->prev->next = nexthop->next;
74549 + else
74550 + rib->nexthop = nexthop->next;
74551 + rib->nexthop_num--;
74554 - return nexthop;
74555 +/* Free nexthop. */
74556 +void
74557 +nexthop_free (struct nexthop *nexthop)
74559 + if (nexthop->ifname)
74560 + XFREE (0, nexthop->ifname);
74561 + XFREE (MTYPE_NEXTHOP, nexthop);
74563 -#endif /* HAVE_IPV6 */
74565 struct nexthop *
74566 -nexthop_blackhole_add (struct rib *rib)
74567 +nexthop_zapi_nexthop_add(struct rib *rib, struct zapi_nexthop* znh)
74569 struct nexthop *nexthop;
74571 nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
74572 memset (nexthop, 0, sizeof (struct nexthop));
74573 - nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
74574 - SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
74576 - nexthop_add (rib, nexthop);
74577 + zapi_nexthop2nexthop(znh, nexthop);
74578 + nexthop_add(rib, nexthop);
74580 return nexthop;
74582 @@ -339,33 +603,54 @@
74583 /* If force flag is not set, do not modify falgs at all for uninstall
74584 the route from FIB. */
74585 static int
74586 -nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
74587 - struct route_node *top)
74588 +nexthop_active_route (struct rib *rib, struct nexthop *nexthop, int set,
74589 + struct route_node *top)
74591 - struct prefix_ipv4 p;
74592 + struct prefix p;
74593 struct route_table *table;
74594 struct route_node *rn;
74595 struct rib *match;
74596 struct nexthop *newhop;
74597 + int afi;
74599 + memset (&p, 0, sizeof (struct prefix));
74601 - if (nexthop->type == NEXTHOP_TYPE_IPV4)
74602 - nexthop->ifindex = 0;
74603 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV4))
74605 + nexthop->ifindex = 0;
74606 + UNSET_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX);
74608 + /* Make lookup prefix. */
74609 + p.family = AF_INET;
74610 + p.prefixlen = IPV4_MAX_PREFIXLEN;
74611 + p.u.prefix4 = nexthop->gate.ipv4;
74612 + afi = AFI_IP;
74614 +#ifdef HAVE_IPV6
74615 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV6))
74617 + nexthop->ifindex = 0;
74618 + UNSET_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX);
74620 + /* Make lookup prefix. */
74621 + p.family = AF_INET6;
74622 + p.prefixlen = IPV6_MAX_PREFIXLEN;
74623 + p.u.prefix6 = nexthop->gate.ipv6;
74624 + afi = AFI_IP6;
74626 +#endif
74627 + else
74628 + return 0;
74630 if (set)
74631 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
74633 - /* Make lookup prefix. */
74634 - memset (&p, 0, sizeof (struct prefix_ipv4));
74635 - p.family = AF_INET;
74636 - p.prefixlen = IPV4_MAX_PREFIXLEN;
74637 - p.prefix = nexthop->gate.ipv4;
74639 /* Lookup table. */
74640 - table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
74641 + table = vrf_table (afi, SAFI_UNICAST, 0);
74642 if (! table)
74643 return 0;
74645 - rn = route_node_match (table, (struct prefix *) &p);
74646 + rn = route_node_match (table, &p);
74647 while (rn)
74649 route_unlock_node (rn);
74650 @@ -396,8 +681,11 @@
74652 /* Directly point connected route. */
74653 newhop = match->nexthop;
74654 - if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
74655 - nexthop->ifindex = newhop->ifindex;
74656 + if (newhop)
74658 + SET_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX);
74659 + nexthop->ifindex = newhop->ifindex;
74662 return 1;
74664 @@ -405,19 +693,29 @@
74666 for (newhop = match->nexthop; newhop; newhop = newhop->next)
74667 if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
74668 + && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_IGNORE)
74669 && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
74671 if (set)
74673 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
74674 nexthop->rtype = newhop->type;
74675 - if (newhop->type == NEXTHOP_TYPE_IPV4 ||
74676 - newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
74678 + if (CHECK_FLAG (newhop->type, ZEBRA_NEXTHOP_IPV4))
74679 nexthop->rgate.ipv4 = newhop->gate.ipv4;
74680 - if (newhop->type == NEXTHOP_TYPE_IFINDEX
74681 - || newhop->type == NEXTHOP_TYPE_IFNAME
74682 - || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
74683 +#ifdef HAVE_IPV6
74684 + else if (CHECK_FLAG (newhop->type, ZEBRA_NEXTHOP_IPV6))
74685 + nexthop->rgate.ipv6 = newhop->gate.ipv6;
74686 +#endif
74687 + else
74688 + assert (0);
74690 + if (CHECK_FLAG (newhop->type, ZEBRA_NEXTHOP_IFINDEX))
74691 nexthop->rifindex = newhop->ifindex;
74692 +#ifdef HAVE_MPLS
74693 + if (CHECK_FLAG (newhop->type, ZEBRA_NEXTHOP_MPLS))
74694 + nexthop->rmpls = newhop->mpls;
74695 +#endif
74697 return 1;
74699 @@ -432,45 +730,78 @@
74700 return 0;
74703 -#ifdef HAVE_IPV6
74704 -/* If force flag is not set, do not modify falgs at all for uninstall
74705 - the route from FIB. */
74706 -static int
74707 -nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
74708 - struct route_node *top)
74709 +int
74710 +rib_check_drop (struct rib *rib)
74712 + struct nexthop *nexthop;
74713 + int flags = 0;
74714 + int drop = 0;
74716 + for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
74718 + if ((CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ||
74719 + CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) &&
74720 + ((CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) &&
74721 + CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_DROP)) ||
74722 + CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_DROP)))
74724 + drop = nexthop->drop;
74725 + break;
74729 + switch (drop)
74731 + case 0:
74732 + break;
74733 + case ZEBRA_DROP_NULL:
74734 + case ZEBRA_DROP_BLACKHOLE:
74735 + flags = ZEBRA_FLAG_BLACKHOLE;
74736 + break;
74737 + case ZEBRA_DROP_REJECT:
74738 + flags = ZEBRA_FLAG_REJECT;
74739 + break;
74740 + default:
74741 + assert(0);
74744 + return flags;
74747 +struct rib *
74748 +rib_match_route (struct prefix *p)
74750 - struct prefix_ipv6 p;
74751 struct route_table *table;
74752 struct route_node *rn;
74753 struct rib *match;
74754 struct nexthop *newhop;
74755 + int afi;
74757 - if (nexthop->type == NEXTHOP_TYPE_IPV6)
74758 - nexthop->ifindex = 0;
74760 - if (set)
74761 - UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
74763 - /* Make lookup prefix. */
74764 - memset (&p, 0, sizeof (struct prefix_ipv6));
74765 - p.family = AF_INET6;
74766 - p.prefixlen = IPV6_MAX_PREFIXLEN;
74767 - p.prefix = nexthop->gate.ipv6;
74768 + switch (p->family)
74770 + case AF_INET:
74771 + afi = AFI_IP;
74772 + p->prefixlen = IPV4_MAX_PREFIXLEN;
74773 + break;
74774 + case AF_INET6:
74775 + afi = AFI_IP6;
74776 + p->prefixlen = IPV6_MAX_PREFIXLEN;
74777 + break;
74778 + default:
74779 + assert(0);
74782 /* Lookup table. */
74783 - table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
74784 + table = vrf_table (afi, SAFI_UNICAST, 0);
74785 if (! table)
74786 return 0;
74788 - rn = route_node_match (table, (struct prefix *) &p);
74789 + rn = route_node_match (table, p);
74791 while (rn)
74793 route_unlock_node (rn);
74795 - /* If lookup self prefix return immidiately. */
74796 - if (rn == top)
74797 - return 0;
74799 /* Pick up selected route. */
74800 for (match = rn->info; match; match = match->next)
74801 if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
74802 @@ -478,94 +809,7 @@
74804 /* If there is no selected route or matched route is EGP, go up
74805 tree. */
74806 - if (! match
74807 - || match->type == ZEBRA_ROUTE_BGP)
74809 - do {
74810 - rn = rn->parent;
74811 - } while (rn && rn->info == NULL);
74812 - if (rn)
74813 - route_lock_node (rn);
74815 - else
74817 - if (match->type == ZEBRA_ROUTE_CONNECT)
74819 - /* Directly point connected route. */
74820 - newhop = match->nexthop;
74822 - if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
74823 - nexthop->ifindex = newhop->ifindex;
74825 - return 1;
74827 - else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
74829 - for (newhop = match->nexthop; newhop; newhop = newhop->next)
74830 - if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
74831 - && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
74833 - if (set)
74835 - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
74836 - nexthop->rtype = newhop->type;
74837 - if (newhop->type == NEXTHOP_TYPE_IPV6
74838 - || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
74839 - || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
74840 - nexthop->rgate.ipv6 = newhop->gate.ipv6;
74841 - if (newhop->type == NEXTHOP_TYPE_IFINDEX
74842 - || newhop->type == NEXTHOP_TYPE_IFNAME
74843 - || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
74844 - || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
74845 - nexthop->rifindex = newhop->ifindex;
74847 - return 1;
74849 - return 0;
74851 - else
74853 - return 0;
74857 - return 0;
74859 -#endif /* HAVE_IPV6 */
74861 -struct rib *
74862 -rib_match_ipv4 (struct in_addr addr)
74864 - struct prefix_ipv4 p;
74865 - struct route_table *table;
74866 - struct route_node *rn;
74867 - struct rib *match;
74868 - struct nexthop *newhop;
74870 - /* Lookup table. */
74871 - table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
74872 - if (! table)
74873 - return 0;
74875 - memset (&p, 0, sizeof (struct prefix_ipv4));
74876 - p.family = AF_INET;
74877 - p.prefixlen = IPV4_MAX_PREFIXLEN;
74878 - p.prefix = addr;
74880 - rn = route_node_match (table, (struct prefix *) &p);
74882 - while (rn)
74884 - route_unlock_node (rn);
74886 - /* Pick up selected route. */
74887 - for (match = rn->info; match; match = match->next)
74888 - if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
74889 - break;
74891 - /* If there is no selected route or matched route is EGP, go up
74892 - tree. */
74893 - if (! match
74894 + if (! match
74895 || match->type == ZEBRA_ROUTE_BGP)
74897 do {
74898 @@ -582,7 +826,8 @@
74899 else
74901 for (newhop = match->nexthop; newhop; newhop = newhop->next)
74902 - if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
74903 + if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
74904 + && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_IGNORE))
74905 return match;
74906 return NULL;
74908 @@ -592,19 +837,32 @@
74911 struct rib *
74912 -rib_lookup_ipv4 (struct prefix_ipv4 *p)
74913 +rib_lookup_route (struct prefix *p)
74915 struct route_table *table;
74916 struct route_node *rn;
74917 struct rib *match;
74918 struct nexthop *nexthop;
74919 + int afi;
74921 + switch (p->family)
74923 + case AF_INET:
74924 + afi = AFI_IP;
74925 + break;
74926 + case AF_INET6:
74927 + afi = AFI_IP6;
74928 + break;
74929 + default:
74930 + assert(0);
74933 /* Lookup table. */
74934 - table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
74935 + table = vrf_table (afi, SAFI_UNICAST, 0);
74936 if (! table)
74937 return 0;
74939 - rn = route_node_lookup (table, (struct prefix *) p);
74940 + rn = route_node_lookup (table, p);
74942 /* No route for this prefix. */
74943 if (! rn)
74944 @@ -625,15 +883,16 @@
74945 return match;
74947 for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
74948 - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
74949 + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
74950 + && ! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_IGNORE))
74951 return match;
74953 return NULL;
74957 - * This clone function, unlike its original rib_lookup_ipv4(), checks
74958 - * if specified IPv4 route record (prefix/mask -> gate) exists in
74959 + * This clone function, unlike its original rib_lookup_route(), checks
74960 + * if specified route record (prefix/mask -> gate) exists in
74961 * the whole RIB and has ZEBRA_FLAG_SELECTED set.
74963 * Return values:
74964 @@ -644,20 +903,33 @@
74965 * 3: no matches found
74968 -rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
74969 +rib_lookup_route_nexthop (struct prefix *p, struct zapi_nexthop *znh)
74971 struct route_table *table;
74972 struct route_node *rn;
74973 struct rib *match;
74974 struct nexthop *nexthop;
74975 + int afi;
74977 + switch (p->family)
74979 + case AF_INET:
74980 + afi = AFI_IP;
74981 + break;
74982 + case AF_INET6:
74983 + afi = AFI_IP6;
74984 + break;
74985 + default:
74986 + assert(0);
74989 /* Lookup table. */
74990 - table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
74991 + table = vrf_table (afi, SAFI_UNICAST, 0);
74992 if (! table)
74993 return ZEBRA_RIB_LOOKUP_ERROR;
74995 /* Scan the RIB table for exactly matching RIB entry. */
74996 - rn = route_node_lookup (table, (struct prefix *) p);
74997 + rn = route_node_lookup (table, p);
74999 /* No route for this prefix. */
75000 if (! rn)
75001 @@ -687,17 +959,17 @@
75002 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
75004 /* We are happy with either direct or recursive hexthop */
75005 - if (nexthop->gate.ipv4.s_addr == qgate->sin.sin_addr.s_addr ||
75006 - nexthop->rgate.ipv4.s_addr == qgate->sin.sin_addr.s_addr)
75007 + if (zapi_nexthop_match_nexthop(znh, nexthop,
75008 + ZEBRA_NEXTHOP_IPV4|ZEBRA_NEXTHOP_IPV6))
75009 return ZEBRA_RIB_FOUND_EXACT;
75010 else
75012 if (IS_ZEBRA_DEBUG_RIB)
75014 char gate_buf[INET_ADDRSTRLEN], rgate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
75015 - inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
75016 - inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, rgate_buf, INET_ADDRSTRLEN);
75017 - inet_ntop (AF_INET, &qgate->sin.sin_addr.s_addr, qgate_buf, INET_ADDRSTRLEN);
75018 + inet_ntop (p->family, &nexthop->gate, gate_buf, INET_ADDRSTRLEN);
75019 + inet_ntop (p->family, &nexthop->rgate, rgate_buf, INET_ADDRSTRLEN);
75020 + inet_ntop (p->family, &znh->gw, qgate_buf, INET_ADDRSTRLEN);
75021 zlog_debug ("%s: qgate == %s, gate == %s, rgate == %s", __func__, qgate_buf, gate_buf, rgate_buf);
75023 return ZEBRA_RIB_FOUND_NOGATE;
75024 @@ -707,66 +979,6 @@
75025 return ZEBRA_RIB_NOTFOUND;
75028 -#ifdef HAVE_IPV6
75029 -struct rib *
75030 -rib_match_ipv6 (struct in6_addr *addr)
75032 - struct prefix_ipv6 p;
75033 - struct route_table *table;
75034 - struct route_node *rn;
75035 - struct rib *match;
75036 - struct nexthop *newhop;
75038 - /* Lookup table. */
75039 - table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
75040 - if (! table)
75041 - return 0;
75043 - memset (&p, 0, sizeof (struct prefix_ipv6));
75044 - p.family = AF_INET6;
75045 - p.prefixlen = IPV6_MAX_PREFIXLEN;
75046 - IPV6_ADDR_COPY (&p.prefix, addr);
75048 - rn = route_node_match (table, (struct prefix *) &p);
75050 - while (rn)
75052 - route_unlock_node (rn);
75054 - /* Pick up selected route. */
75055 - for (match = rn->info; match; match = match->next)
75056 - if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
75057 - break;
75059 - /* If there is no selected route or matched route is EGP, go up
75060 - tree. */
75061 - if (! match
75062 - || match->type == ZEBRA_ROUTE_BGP)
75064 - do {
75065 - rn = rn->parent;
75066 - } while (rn && rn->info == NULL);
75067 - if (rn)
75068 - route_lock_node (rn);
75070 - else
75072 - if (match->type == ZEBRA_ROUTE_CONNECT)
75073 - /* Directly point connected route. */
75074 - return match;
75075 - else
75077 - for (newhop = match->nexthop; newhop; newhop = newhop->next)
75078 - if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB))
75079 - return match;
75080 - return NULL;
75084 - return NULL;
75086 -#endif /* HAVE_IPV6 */
75088 #define RIB_SYSTEM_ROUTE(R) \
75089 ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
75091 @@ -789,76 +1001,105 @@
75092 extern char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];
75093 struct route_map *rmap;
75094 int family;
75095 + int try = 0;
75096 + int match = 0;
75098 family = 0;
75099 - switch (nexthop->type)
75100 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFNAME))
75102 - case NEXTHOP_TYPE_IFINDEX:
75103 - ifp = if_lookup_by_index (nexthop->ifindex);
75104 - if (ifp && if_is_operative(ifp))
75105 - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
75106 - else
75107 - UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
75108 - break;
75109 - case NEXTHOP_TYPE_IPV6_IFNAME:
75110 - family = AFI_IP6;
75111 - case NEXTHOP_TYPE_IFNAME:
75112 + try++;
75113 ifp = if_lookup_by_name (nexthop->ifname);
75114 if (ifp && if_is_operative(ifp))
75116 if (set)
75117 - nexthop->ifindex = ifp->ifindex;
75118 - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
75120 + nexthop->ifindex = ifp->ifindex;
75121 + SET_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX);
75122 + UNSET_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFNAME);
75124 + match++;
75126 else
75128 if (set)
75129 - nexthop->ifindex = 0;
75130 - UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
75132 + nexthop->ifindex = 0;
75133 + UNSET_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX);
75134 + SET_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFNAME);
75137 - break;
75138 - case NEXTHOP_TYPE_IPV4:
75139 - case NEXTHOP_TYPE_IPV4_IFINDEX:
75141 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX))
75143 + try++;
75144 + ifp = if_lookup_by_index (nexthop->ifindex);
75145 + if (ifp && if_is_up (ifp)) {
75146 + match++;
75150 +#ifdef HAVE_MPLS
75151 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_MPLS))
75153 + try++;
75154 + if (mpls_out_segment_find(nexthop->mpls))
75155 + match++;
75157 +#endif
75159 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV4))
75161 family = AFI_IP;
75162 - if (nexthop_active_ipv4 (rib, nexthop, set, rn))
75163 - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
75164 - else
75165 - UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
75166 - break;
75167 + try++;
75168 + if (nexthop_active_route (rib, nexthop, set, rn)) {
75169 + match++;
75172 #ifdef HAVE_IPV6
75173 - case NEXTHOP_TYPE_IPV6:
75174 - family = AFI_IP6;
75175 - if (nexthop_active_ipv6 (rib, nexthop, set, rn))
75176 - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
75177 - else
75178 - UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
75179 - break;
75180 - case NEXTHOP_TYPE_IPV6_IFINDEX:
75181 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV6))
75183 family = AFI_IP6;
75184 - if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
75186 - ifp = if_lookup_by_index (nexthop->ifindex);
75187 - if (ifp && if_is_operative(ifp))
75188 - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
75189 - else
75190 - UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
75192 + try++;
75193 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX))
75195 + if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
75197 + ifp = if_lookup_by_index (nexthop->ifindex);
75198 + if (ifp && if_is_operative(ifp)) {
75199 + match++;
75202 + else
75204 + if (nexthop_active_route (rib, nexthop, set, rn)) {
75205 + match++;
75209 else
75211 - if (nexthop_active_ipv6 (rib, nexthop, set, rn))
75212 - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
75213 - else
75214 - UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
75216 - break;
75218 + if (nexthop_active_route (rib, nexthop, set, rn)) {
75219 + match++;
75223 #endif /* HAVE_IPV6 */
75224 - case NEXTHOP_TYPE_BLACKHOLE:
75225 - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
75226 - break;
75227 - default:
75228 - break;
75229 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_DROP))
75231 + try++;
75232 + match++;
75234 - if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
75236 + try++;
75237 + if (!CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_IGNORE))
75238 + match++;
75240 + if (try && (try == match))
75241 + SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
75242 + else
75243 + UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
75245 + if (!CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
75246 return 0;
75248 if (RIB_SYSTEM_ROUTE(rib) ||
75249 @@ -898,15 +1139,27 @@
75251 rib->nexthop_active_num = 0;
75252 UNSET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
75253 + UNSET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE|ZEBRA_FLAG_REJECT);
75255 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
75257 + /*
75258 + * we want to process all nexthops even IGNORED ones incase
75259 + * a newly ignored nexthop was active, that should trigger
75260 + * a route change. So nexthop_active_check is responsible
75261 + * for checking IGNORED and handling accordingly
75262 + */
75263 prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
75264 if ((new_active = nexthop_active_check (rn, rib, nexthop, set)))
75265 rib->nexthop_active_num++;
75266 if (prev_active != new_active)
75267 SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
75269 +#ifdef HAVE_MPLS
75270 + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_CHANGED_MPLS))
75271 + SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
75272 +#endif
75273 + SET_FLAG (rib->flags, rib_check_drop(rib));
75274 return rib->nexthop_active_num;
75277 @@ -939,7 +1192,7 @@
75280 /* Uninstall the route from kernel. */
75281 -static int
75282 +int
75283 rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
75285 int ret = 0;
75286 @@ -1096,7 +1349,11 @@
75287 __func__, buf, rn->p.prefixlen, select, fib);
75288 if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
75290 - redistribute_delete (&rn->p, select);
75291 +#ifdef HAVE_MPLS
75292 + if (!CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED_MPLS))
75293 +#endif
75294 + redistribute_delete (&rn->p, select);
75296 if (! RIB_SYSTEM_ROUTE (select))
75297 rib_uninstall_kernel (rn, select);
75299 @@ -1105,7 +1362,11 @@
75301 if (! RIB_SYSTEM_ROUTE (select))
75302 rib_install_kernel (rn, select);
75303 - redistribute_add (&rn->p, select);
75305 +#ifdef HAVE_MPLS
75306 + if (!CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED_MPLS))
75307 +#endif
75308 + redistribute_add (&rn->p, select);
75310 else if (! RIB_SYSTEM_ROUTE (select))
75312 @@ -1125,6 +1386,9 @@
75313 if (! installed)
75314 rib_install_kernel (rn, select);
75316 +#ifdef HAVE_MPLS
75317 + UNSET_FLAG (select->flags, ZEBRA_FLAG_CHANGED_MPLS);
75318 +#endif
75319 goto end;
75322 @@ -1161,7 +1425,13 @@
75323 if (! RIB_SYSTEM_ROUTE (select))
75324 rib_install_kernel (rn, select);
75325 SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
75326 - redistribute_add (&rn->p, select);
75327 +#ifdef HAVE_MPLS
75328 + if (!CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED_MPLS))
75329 +#endif
75330 + redistribute_add (&rn->p, select);
75331 +#ifdef HAVE_MPLS
75332 + UNSET_FLAG (select->flags, ZEBRA_FLAG_CHANGED_MPLS);
75333 +#endif
75336 /* FIB route was removed, should be deleted */
75337 @@ -1268,7 +1538,7 @@
75340 /* Add route_node to work queue and schedule processing */
75341 -static void
75342 +void
75343 rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
75345 char buf[INET_ADDRSTRLEN];
75346 @@ -1519,24 +1789,97 @@
75350 -rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
75351 - struct in_addr *gate, struct in_addr *src,
75352 - unsigned int ifindex, u_int32_t vrf_id,
75353 - u_int32_t metric, u_char distance)
75354 +rib_find_nexthop2 (int owner, struct rib *rib_in, struct nexthop *nh_in,
75355 + struct rib **rib_out, struct nexthop **nh_out)
75357 + struct nexthop *nh = NULL;
75358 + struct rib *rib = NULL;
75360 + for (rib = rib_in; rib; rib = rib->next)
75362 + if ((owner >= 0) && (rib->type != owner))
75363 + continue;
75365 + for (nh = rib->nexthop; nh; nh = nh->next)
75367 + if (nexthop_match(nh_in, nh,
75368 + (ZEBRA_NEXTHOP_ALL & (~ZEBRA_NEXTHOP_MPLS))))
75370 + *rib_out = rib;
75371 + *nh_out = nh;
75372 + return 0;
75376 + return 1;
75379 +int
75380 +rib_find_nexthop (int owner, struct prefix *p_in, struct nexthop *nh_in,
75381 + struct route_node **rn_out, struct rib **rib_out, struct nexthop **nh_out)
75383 + struct route_table *table = NULL;
75384 + struct route_node *rn = NULL;
75386 + *rn_out = NULL;
75387 + *rib_out = NULL;
75388 + *nh_out = NULL;
75390 + switch (p_in->family)
75392 + case AF_INET:
75393 + table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
75394 + break;
75395 + case AF_INET6:
75396 + table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
75397 + break;
75398 + default:
75399 + assert(0);
75402 + if ((!table) || (!(rn = route_node_lookup (table, p_in))))
75403 + return 1;
75405 + if (!rib_find_nexthop2(owner, rn->info, nh_in, rib_out, nh_out))
75407 + *rn_out = rn;
75408 + return 0;
75410 + route_unlock_node (rn);
75411 + return 1;
75414 +int
75415 +rib_add_route (int type, int flags, struct prefix *p,
75416 + struct zapi_nexthop *nh, u_int32_t vrf_id,
75417 + u_int32_t metric, u_char distance)
75419 struct rib *rib;
75420 struct rib *same = NULL;
75421 struct route_table *table;
75422 struct route_node *rn;
75423 struct nexthop *nexthop;
75424 + int afi;
75426 + switch (p->family)
75428 + case AF_INET:
75429 + afi = AFI_IP;
75430 + break;
75431 + case AF_INET6:
75432 + afi = AFI_IP6;
75433 + break;
75434 + default:
75435 + assert(0);
75438 /* Lookup table. */
75439 - table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
75440 + table = vrf_table (afi, SAFI_UNICAST, 0);
75441 if (! table)
75442 return 0;
75444 /* Make it sure prefixlen is applied to the prefix. */
75445 - apply_mask_ipv4 (p);
75446 + apply_mask (p);
75448 /* Set default distance by route type. */
75449 if (distance == 0)
75450 @@ -1548,8 +1891,16 @@
75451 distance = 200;
75454 +#ifdef HAVE_IPV6
75455 + /* Filter bogus route. */
75456 + if (afi == AFI_IP6 &&
75457 + rib_bogus_ipv6 (type, (struct prefix_ipv6*)p, &nh->gw.ipv6,
75458 + nh->intf.index, 0))
75459 + return 0;
75460 +#endif
75462 /* Lookup route node.*/
75463 - rn = route_node_get (table, (struct prefix *) p);
75464 + rn = route_node_get (table, p);
75466 /* If same type of route are installed, treat it as a implicit
75467 withdraw. */
75468 @@ -1567,8 +1918,8 @@
75470 /* Duplicate connected route comes in. */
75471 else if ((nexthop = rib->nexthop) &&
75472 - nexthop->type == NEXTHOP_TYPE_IFINDEX &&
75473 - nexthop->ifindex == ifindex &&
75474 + zapi_nexthop_match_nexthop(nh, nexthop,
75475 + ZEBRA_NEXTHOP_IPV4|ZEBRA_NEXTHOP_IPV6) &&
75476 !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
75478 rib->refcnt++;
75479 @@ -1587,20 +1938,16 @@
75480 rib->uptime = time (NULL);
75482 /* Nexthop settings. */
75483 - if (gate)
75485 - if (ifindex)
75486 - nexthop_ipv4_ifindex_add (rib, gate, src, ifindex);
75487 - else
75488 - nexthop_ipv4_add (rib, gate, src);
75490 - else
75491 - nexthop_ifindex_add (rib, ifindex);
75492 + nexthop_zapi_nexthop_add(rib, nh);
75494 /* If this route is kernel route, set FIB flag to the route. */
75495 if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
75496 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
75497 - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
75499 + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_IGNORE))
75500 + continue;
75501 + SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
75504 /* Link new rib to node.*/
75505 if (IS_ZEBRA_DEBUG_RIB)
75506 @@ -1676,7 +2023,7 @@
75509 /* This is an exported helper to rtm_read() to dump the strange
75510 - * RIB entry found by rib_lookup_ipv4_route()
75511 + * RIB entry found by rib_lookup_route_nexthop()
75514 void rib_lookup_and_dump (struct prefix_ipv4 * p)
75515 @@ -1777,19 +2124,33 @@
75519 -rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib)
75520 +rib_add_multipath (struct prefix *p, struct rib *rib)
75522 struct route_table *table;
75523 struct route_node *rn;
75524 struct rib *same;
75525 struct nexthop *nexthop;
75527 - /* Lookup table. */
75528 - table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
75529 + int afi;
75531 + switch (p->family)
75533 + case AF_INET:
75534 + afi = AFI_IP;
75535 + break;
75536 + case AF_INET6:
75537 + afi = AFI_IP6;
75538 + break;
75539 + default:
75540 + assert(0);
75544 + /* Lookup table. */
75545 + table = vrf_table (afi, SAFI_UNICAST, 0);
75546 if (! table)
75547 return 0;
75548 /* Make it sure prefixlen is applied to the prefix. */
75549 - apply_mask_ipv4 (p);
75550 + apply_mask (p);
75552 /* Set default distance by route type. */
75553 if (rib->distance == 0)
75554 @@ -1803,7 +2164,7 @@
75557 /* Lookup route node.*/
75558 - rn = route_node_get (table, (struct prefix *) p);
75559 + rn = route_node_get (table, p);
75561 /* If same type of route are installed, treat it as a implicit
75562 withdraw. */
75563 @@ -1820,7 +2181,11 @@
75564 /* If this route is kernel route, set FIB flag to the route. */
75565 if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT)
75566 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
75567 - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
75569 + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_IGNORE))
75570 + continue;
75571 + SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
75574 /* Link new rib to node.*/
75575 rib_addnode (rn, rib);
75576 @@ -1847,53 +2212,55 @@
75577 return 0;
75580 -/* XXX factor with rib_delete_ipv6 */
75582 -rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p,
75583 - struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
75584 +rib_delete_route (int type, int flags, struct prefix *p,
75585 + struct zapi_nexthop *nh, u_int32_t vrf_id)
75587 struct route_table *table;
75588 struct route_node *rn;
75589 struct rib *rib;
75590 struct rib *fib = NULL;
75591 struct rib *same = NULL;
75592 - struct nexthop *nexthop;
75593 - char buf1[BUFSIZ];
75594 - char buf2[BUFSIZ];
75595 + char prefix_str[BUFSIZ];
75596 + int afi;
75598 + switch (p->family)
75600 + case AF_INET:
75601 + afi = AFI_IP;
75602 + break;
75603 + case AF_INET6:
75604 + afi = AFI_IP6;
75605 + break;
75606 + default:
75607 + assert(0);
75610 /* Lookup table. */
75611 - table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
75612 + table = vrf_table (afi, SAFI_UNICAST, 0);
75613 if (! table)
75614 return 0;
75616 /* Apply mask. */
75617 - apply_mask_ipv4 (p);
75618 + apply_mask (p);
75620 + if (IS_ZEBRA_DEBUG_KERNEL)
75622 + inet_ntop (p->family, &p->u.prefix, prefix_str, BUFSIZ),
75623 + snprintf(&prefix_str[strlen(prefix_str)], BUFSIZ - strlen(prefix_str),
75624 + "/%d", p->prefixlen);
75625 + zapi_nexthop_str(nh, &prefix_str[strlen(prefix_str)],
75626 + BUFSIZ - strlen(prefix_str));
75628 - if (IS_ZEBRA_DEBUG_KERNEL && gate)
75629 - zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
75630 - inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
75631 - p->prefixlen,
75632 - inet_ntoa (*gate),
75633 - ifindex);
75634 + zlog_debug ("rib_delete_route(): route delete %s", prefix_str);
75637 /* Lookup route node. */
75638 - rn = route_node_lookup (table, (struct prefix *) p);
75639 + rn = route_node_lookup (table, p);
75640 if (! rn)
75642 if (IS_ZEBRA_DEBUG_KERNEL)
75644 - if (gate)
75645 - zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
75646 - inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
75647 - p->prefixlen,
75648 - inet_ntop (AF_INET, gate, buf2, BUFSIZ),
75649 - ifindex);
75650 - else
75651 - zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
75652 - inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
75653 - p->prefixlen,
75654 - ifindex);
75656 + zlog_debug ("route %s doesn't exist in rib", prefix_str);
75657 return ZEBRA_ERR_RTNOEXIST;
75660 @@ -1908,36 +2275,36 @@
75662 if (rib->type != type)
75663 continue;
75664 - if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
75665 - nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
75667 - if (rib->refcnt)
75669 + /* Make sure that the route found matched */
75670 + if (zapi_nexthop_match_nexthop(nh, rib->nexthop, ZEBRA_NEXTHOP_ALL))
75672 + if (rib->type == ZEBRA_ROUTE_CONNECT)
75674 - rib->refcnt--;
75675 - route_unlock_node (rn);
75676 - route_unlock_node (rn);
75677 - return 0;
75678 + if (rib->refcnt)
75680 + rib->refcnt--;
75681 + route_unlock_node (rn);
75682 + route_unlock_node (rn);
75683 + return 0;
75685 + same = rib;
75686 + break;
75688 - same = rib;
75689 - break;
75691 - /* Make sure that the route found has the same gateway. */
75692 - else if (gate == NULL ||
75693 - ((nexthop = rib->nexthop) &&
75694 - (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) ||
75695 - IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate))))
75697 - same = rib;
75698 - break;
75700 + else
75702 + same = rib;
75703 + break;
75708 - /* If same type of route can't be found and this message is from
75709 - kernel. */
75710 + /* If same type of route can't be found and this message is from kernel. */
75711 if (! same)
75713 if (fib && type == ZEBRA_ROUTE_KERNEL)
75715 + struct nexthop *nexthop = NULL;
75716 /* Unset flags. */
75717 for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
75718 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
75719 @@ -1947,21 +2314,8 @@
75720 else
75722 if (IS_ZEBRA_DEBUG_KERNEL)
75724 - if (gate)
75725 - zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
75726 - inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
75727 - p->prefixlen,
75728 - inet_ntop (AF_INET, gate, buf2, BUFSIZ),
75729 - ifindex,
75730 - type);
75731 - else
75732 - zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
75733 - inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ),
75734 - p->prefixlen,
75735 - ifindex,
75736 - type);
75738 + zlog_debug ("route %s type %d doesn't exist in rib",
75739 + prefix_str, type);
75740 route_unlock_node (rn);
75741 return ZEBRA_ERR_RTNOEXIST;
75743 @@ -1973,17 +2327,84 @@
75744 route_unlock_node (rn);
75745 return 0;
75748 +static int
75749 +static_route_compare(struct static_route *a, struct static_route *b, int mask)
75751 + int both = (a->nh.type & b->nh.type) & mask;
75752 + int ret = 0;
75754 + if (a->distance < b->distance)
75755 + return -1;
75757 + if (a->distance > b->distance)
75758 + return 1;
75760 + if (CHECK_FLAG (both, ZEBRA_NEXTHOP_IPV4))
75762 + ret = IPV4_ADDR_CMP(&a->nh.gw.ipv4, &b->nh.gw.ipv4);
75763 + if (ret)
75764 + return ret;
75766 + else if (CHECK_FLAG (both, ZEBRA_NEXTHOP_IPV6))
75768 + ret = IPV6_ADDR_CMP(&a->nh.gw.ipv6, &b->nh.gw.ipv6);
75769 + if (ret)
75770 + return ret;
75773 + if (CHECK_FLAG (both, ZEBRA_NEXTHOP_IFNAME))
75775 + ret = strncmp(a->nh.intf.name, b->nh.intf.name, IFNAMSIZ);
75776 + if (ret)
75777 + return ret;
75779 + else if (CHECK_FLAG (both, ZEBRA_NEXTHOP_IFINDEX))
75781 + if (a->nh.intf.index < b->nh.intf.index)
75782 + return -1;
75783 + if (a->nh.intf.index > b->nh.intf.index)
75784 + return 1;
75786 +#ifdef HAVE_MPLS
75787 + if (CHECK_FLAG (both, ZEBRA_NEXTHOP_MPLS))
75789 + int aos = mpls_out_segment_find_index_by_nexthop(&a->nh);
75790 + int bos = mpls_out_segment_find_index_by_nexthop(&b->nh);
75791 + if (aos < bos)
75792 + return -1;
75793 + if (aos > bos)
75794 + return 1;
75796 +#endif
75798 + return 0;
75801 /* Install static route into rib. */
75802 static void
75803 -static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
75804 +static_install_route (struct prefix *p, struct zapi_nexthop *nexthop, int distance)
75806 struct rib *rib;
75807 struct route_node *rn;
75808 struct route_table *table;
75809 + int new = 0;
75810 + int afi;
75812 + switch (p->family)
75814 + case AF_INET:
75815 + afi = AFI_IP;
75816 + break;
75817 + case AF_INET6:
75818 + afi = AFI_IP6;
75819 + break;
75820 + default:
75821 + assert(0);
75824 /* Lookup table. */
75825 - table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
75826 + table = vrf_table (afi, SAFI_UNICAST, 0);
75827 if (! table)
75828 return;
75830 @@ -1994,88 +2415,66 @@
75831 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
75832 continue;
75834 - if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
75835 + if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == distance)
75836 break;
75839 - if (rib)
75841 - /* Same distance static route is there. Update it with new
75842 - nexthop. */
75843 - route_unlock_node (rn);
75844 - switch (si->type)
75846 - case STATIC_IPV4_GATEWAY:
75847 - nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
75848 - break;
75849 - case STATIC_IPV4_IFNAME:
75850 - nexthop_ifname_add (rib, si->gate.ifname);
75851 - break;
75852 - case STATIC_IPV4_BLACKHOLE:
75853 - nexthop_blackhole_add (rib);
75854 - break;
75856 - rib_queue_add (&zebrad, rn);
75858 - else
75859 + if (!rib)
75861 + new = 1;
75863 /* This is new static route. */
75864 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
75866 rib->type = ZEBRA_ROUTE_STATIC;
75867 - rib->distance = si->distance;
75868 + rib->distance = distance;
75869 rib->metric = 0;
75870 rib->nexthop_num = 0;
75872 + else
75874 + /* Same distance static route is there. Update it with new
75875 + nexthop. */
75876 + route_unlock_node (rn);
75879 - switch (si->type)
75881 - case STATIC_IPV4_GATEWAY:
75882 - nexthop_ipv4_add (rib, &si->gate.ipv4, NULL);
75883 - break;
75884 - case STATIC_IPV4_IFNAME:
75885 - nexthop_ifname_add (rib, si->gate.ifname);
75886 - break;
75887 - case STATIC_IPV4_BLACKHOLE:
75888 - nexthop_blackhole_add (rib);
75889 - break;
75892 - /* Save the flags of this static routes (reject, blackhole) */
75893 - rib->flags = si->flags;
75894 + nexthop_zapi_nexthop_add(rib, nexthop);
75896 + if (new)
75898 /* Link this rib to the tree. */
75899 rib_addnode (rn, rib);
75903 -static int
75904 -static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si)
75906 - if (nexthop->type == NEXTHOP_TYPE_IPV4
75907 - && si->type == STATIC_IPV4_GATEWAY
75908 - && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4))
75909 - return 1;
75910 - if (nexthop->type == NEXTHOP_TYPE_IFNAME
75911 - && si->type == STATIC_IPV4_IFNAME
75912 - && strcmp (nexthop->ifname, si->gate.ifname) == 0)
75913 - return 1;
75914 - if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE
75915 - && si->type == STATIC_IPV4_BLACKHOLE)
75916 - return 1;
75917 - return 0;
75918 + else
75920 + rib_queue_add (&zebrad, rn);
75924 /* Uninstall static route from RIB. */
75925 static void
75926 -static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
75927 +static_uninstall_route (struct prefix *p, struct zapi_nexthop *znexthop, int distance)
75929 struct route_node *rn;
75930 struct rib *rib;
75931 struct nexthop *nexthop;
75932 struct route_table *table;
75933 + int afi;
75935 + switch (p->family)
75937 + case AF_INET:
75938 + afi = AFI_IP;
75939 + break;
75940 + case AF_INET6:
75941 + afi = AFI_IP6;
75942 + break;
75943 + default:
75944 + assert(0);
75947 /* Lookup table. */
75948 - table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
75949 + table = vrf_table (afi, SAFI_UNICAST, 0);
75950 if (! table)
75951 return;
75953 @@ -2089,7 +2488,7 @@
75954 if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
75955 continue;
75957 - if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
75958 + if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == distance)
75959 break;
75962 @@ -2101,7 +2500,7 @@
75964 /* Lookup nexthop. */
75965 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
75966 - if (static_ipv4_nexthop_same (nexthop, si))
75967 + if (zapi_nexthop_match_nexthop (znexthop, nexthop, ZEBRA_NEXTHOP_ALL))
75968 break;
75970 /* Can't find nexthop. */
75971 @@ -2128,82 +2527,67 @@
75973 /* Add static route into static route configuration. */
75975 -static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
75976 - u_char flags, u_char distance, u_int32_t vrf_id)
75977 +static_add_route (struct prefix *p, struct zapi_nexthop *nexthop,
75978 + u_char distance, u_int32_t vrf_id)
75980 - u_char type = 0;
75981 struct route_node *rn;
75982 - struct static_ipv4 *si;
75983 - struct static_ipv4 *pp;
75984 - struct static_ipv4 *cp;
75985 - struct static_ipv4 *update = NULL;
75986 + struct static_route *si;
75987 + struct static_route *pp;
75988 + struct static_route *cp;
75989 + struct static_route *update = NULL;
75990 struct route_table *stable;
75991 + int afi;
75993 + switch (p->family)
75995 + case AF_INET:
75996 + afi = AFI_IP;
75997 + break;
75998 + case AF_INET6:
75999 + afi = AFI_IP6;
76000 + break;
76001 + default:
76002 + assert(0);
76005 /* Lookup table. */
76006 - stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
76007 + stable = vrf_static_table (afi, SAFI_UNICAST, vrf_id);
76008 if (! stable)
76009 return -1;
76011 /* Lookup static route prefix. */
76012 rn = route_node_get (stable, p);
76014 - /* Make flags. */
76015 - if (gate)
76016 - type = STATIC_IPV4_GATEWAY;
76017 - else if (ifname)
76018 - type = STATIC_IPV4_IFNAME;
76019 - else
76020 - type = STATIC_IPV4_BLACKHOLE;
76022 /* Do nothing if there is a same static route. */
76023 for (si = rn->info; si; si = si->next)
76025 - if (type == si->type
76026 - && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
76027 - && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
76029 - if (distance == si->distance)
76031 - route_unlock_node (rn);
76032 - return 0;
76034 - else
76035 - update = si;
76038 + if (zapi_nexthop_match_static_route(distance, nexthop, si))
76040 + route_unlock_node (rn);
76041 + return 0;
76043 + else if (afi == AFI_IP)
76044 + update = si;
76046 - /* Distance changed. */
76047 + /* Distance or nexthop changed. */
76048 if (update)
76049 - static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
76050 + static_delete_route (p, nexthop, update->distance, vrf_id);
76052 /* Make new static route structure. */
76053 - si = XMALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
76054 - memset (si, 0, sizeof (struct static_ipv4));
76055 + si = XMALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route));
76056 + memset (si, 0, sizeof (struct static_route));
76058 - si->type = type;
76059 si->distance = distance;
76060 - si->flags = flags;
76062 - if (gate)
76063 - si->gate.ipv4 = *gate;
76064 - if (ifname)
76065 - si->gate.ifname = XSTRDUP (0, ifname);
76066 + memcpy(&si->nh, nexthop, sizeof(struct zapi_nexthop));
76068 /* Add new static route information to the tree with sort by
76069 distance value and gateway address. */
76070 for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
76072 - if (si->distance < cp->distance)
76073 + int cmp = static_route_compare(si, cp, ZEBRA_NEXTHOP_ALL);
76074 + if (cmp < 0)
76075 break;
76076 - if (si->distance > cp->distance)
76077 + if (cmp > 0)
76078 continue;
76079 - if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY)
76081 - if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr))
76082 - break;
76083 - if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr))
76084 - continue;
76088 /* Make linked list. */
76089 @@ -2217,23 +2601,35 @@
76090 si->next = cp;
76092 /* Install into rib. */
76093 - static_install_ipv4 (p, si);
76094 + static_install_route (p, nexthop, distance);
76096 return 1;
76099 /* Delete static route from static route configuration. */
76101 -static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
76102 - u_char distance, u_int32_t vrf_id)
76103 +static_delete_route (struct prefix *p, struct zapi_nexthop *nexthop,
76104 + u_char distance, u_int32_t vrf_id)
76106 - u_char type = 0;
76107 struct route_node *rn;
76108 - struct static_ipv4 *si;
76109 + struct static_route *si;
76110 struct route_table *stable;
76111 + int afi;
76113 + switch (p->family)
76115 + case AF_INET:
76116 + afi = AFI_IP;
76117 + break;
76118 + case AF_INET6:
76119 + afi = AFI_IP6;
76120 + break;
76121 + default:
76122 + assert(0);
76125 /* Lookup table. */
76126 - stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
76127 + stable = vrf_static_table (afi, SAFI_UNICAST, vrf_id);
76128 if (! stable)
76129 return -1;
76131 @@ -2242,19 +2638,9 @@
76132 if (! rn)
76133 return 0;
76135 - /* Make flags. */
76136 - if (gate)
76137 - type = STATIC_IPV4_GATEWAY;
76138 - else if (ifname)
76139 - type = STATIC_IPV4_IFNAME;
76140 - else
76141 - type = STATIC_IPV4_BLACKHOLE;
76143 /* Find same static route is the tree */
76144 for (si = rn->info; si; si = si->next)
76145 - if (type == si->type
76146 - && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4))
76147 - && (! ifname || strcmp (ifname, si->gate.ifname) == 0))
76148 + if (zapi_nexthop_match_static_route(distance, nexthop, si))
76149 break;
76151 /* Can't find static route. */
76152 @@ -2265,7 +2651,7 @@
76155 /* Install into rib. */
76156 - static_uninstall_ipv4 (p, si);
76157 + static_uninstall_route (p, nexthop, distance);
76159 /* Unlink static route from linked list. */
76160 if (si->prev)
76161 @@ -2277,15 +2663,12 @@
76162 route_unlock_node (rn);
76164 /* Free static route configuration. */
76165 - if (ifname)
76166 - XFREE (0, si->gate.ifname);
76167 - XFREE (MTYPE_STATIC_IPV4, si);
76168 + XFREE (MTYPE_STATIC_ROUTE, si);
76170 route_unlock_node (rn);
76172 return 1;
76176 #ifdef HAVE_IPV6
76177 static int
76178 @@ -2308,518 +2691,6 @@
76180 return 0;
76183 -int
76184 -rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
76185 - struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
76186 - u_int32_t metric, u_char distance)
76188 - struct rib *rib;
76189 - struct rib *same = NULL;
76190 - struct route_table *table;
76191 - struct route_node *rn;
76192 - struct nexthop *nexthop;
76194 - /* Lookup table. */
76195 - table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
76196 - if (! table)
76197 - return 0;
76199 - /* Make sure mask is applied. */
76200 - apply_mask_ipv6 (p);
76202 - /* Set default distance by route type. */
76203 - if (!distance)
76204 - distance = route_info[type].distance;
76206 - if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP))
76207 - distance = 200;
76209 - /* Filter bogus route. */
76210 - if (rib_bogus_ipv6 (type, p, gate, ifindex, 0))
76211 - return 0;
76213 - /* Lookup route node.*/
76214 - rn = route_node_get (table, (struct prefix *) p);
76216 - /* If same type of route are installed, treat it as a implicit
76217 - withdraw. */
76218 - for (rib = rn->info; rib; rib = rib->next)
76220 - if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
76221 - continue;
76223 - if (rib->type != type)
76224 - continue;
76225 - if (rib->type != ZEBRA_ROUTE_CONNECT)
76227 - same = rib;
76228 - break;
76230 - else if ((nexthop = rib->nexthop) &&
76231 - nexthop->type == NEXTHOP_TYPE_IFINDEX &&
76232 - nexthop->ifindex == ifindex)
76234 - rib->refcnt++;
76235 - return 0;
76239 - /* Allocate new rib structure. */
76240 - rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
76242 - rib->type = type;
76243 - rib->distance = distance;
76244 - rib->flags = flags;
76245 - rib->metric = metric;
76246 - rib->table = vrf_id;
76247 - rib->nexthop_num = 0;
76248 - rib->uptime = time (NULL);
76250 - /* Nexthop settings. */
76251 - if (gate)
76253 - if (ifindex)
76254 - nexthop_ipv6_ifindex_add (rib, gate, ifindex);
76255 - else
76256 - nexthop_ipv6_add (rib, gate);
76258 - else
76259 - nexthop_ifindex_add (rib, ifindex);
76261 - /* If this route is kernel route, set FIB flag to the route. */
76262 - if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
76263 - for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
76264 - SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
76266 - /* Link new rib to node.*/
76267 - rib_addnode (rn, rib);
76269 - /* Free implicit route.*/
76270 - if (same)
76271 - rib_delnode (rn, same);
76273 - route_unlock_node (rn);
76274 - return 0;
76277 -/* XXX factor with rib_delete_ipv6 */
76278 -int
76279 -rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
76280 - struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id)
76282 - struct route_table *table;
76283 - struct route_node *rn;
76284 - struct rib *rib;
76285 - struct rib *fib = NULL;
76286 - struct rib *same = NULL;
76287 - struct nexthop *nexthop;
76288 - char buf1[BUFSIZ];
76289 - char buf2[BUFSIZ];
76291 - /* Apply mask. */
76292 - apply_mask_ipv6 (p);
76294 - /* Lookup table. */
76295 - table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
76296 - if (! table)
76297 - return 0;
76299 - /* Lookup route node. */
76300 - rn = route_node_lookup (table, (struct prefix *) p);
76301 - if (! rn)
76303 - if (IS_ZEBRA_DEBUG_KERNEL)
76305 - if (gate)
76306 - zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
76307 - inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
76308 - p->prefixlen,
76309 - inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
76310 - ifindex);
76311 - else
76312 - zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
76313 - inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
76314 - p->prefixlen,
76315 - ifindex);
76317 - return ZEBRA_ERR_RTNOEXIST;
76320 - /* Lookup same type route. */
76321 - for (rib = rn->info; rib; rib = rib->next)
76323 - if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
76324 - continue;
76326 - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
76327 - fib = rib;
76329 - if (rib->type != type)
76330 - continue;
76331 - if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) &&
76332 - nexthop->type == NEXTHOP_TYPE_IFINDEX && nexthop->ifindex == ifindex)
76334 - if (rib->refcnt)
76336 - rib->refcnt--;
76337 - route_unlock_node (rn);
76338 - route_unlock_node (rn);
76339 - return 0;
76341 - same = rib;
76342 - break;
76344 - /* Make sure that the route found has the same gateway. */
76345 - else if (gate == NULL ||
76346 - ((nexthop = rib->nexthop) &&
76347 - (IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate) ||
76348 - IPV6_ADDR_SAME (&nexthop->rgate.ipv6, gate))))
76350 - same = rib;
76351 - break;
76355 - /* If same type of route can't be found and this message is from
76356 - kernel. */
76357 - if (! same)
76359 - if (fib && type == ZEBRA_ROUTE_KERNEL)
76361 - /* Unset flags. */
76362 - for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next)
76363 - UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
76365 - UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
76367 - else
76369 - if (IS_ZEBRA_DEBUG_KERNEL)
76371 - if (gate)
76372 - zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
76373 - inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
76374 - p->prefixlen,
76375 - inet_ntop (AF_INET6, gate, buf2, BUFSIZ),
76376 - ifindex,
76377 - type);
76378 - else
76379 - zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
76380 - inet_ntop (AF_INET6, &p->prefix, buf1, BUFSIZ),
76381 - p->prefixlen,
76382 - ifindex,
76383 - type);
76385 - route_unlock_node (rn);
76386 - return ZEBRA_ERR_RTNOEXIST;
76390 - if (same)
76391 - rib_delnode (rn, same);
76393 - route_unlock_node (rn);
76394 - return 0;
76397 -/* Install static route into rib. */
76398 -static void
76399 -static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
76401 - struct rib *rib;
76402 - struct route_table *table;
76403 - struct route_node *rn;
76405 - /* Lookup table. */
76406 - table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
76407 - if (! table)
76408 - return;
76410 - /* Lookup existing route */
76411 - rn = route_node_get (table, p);
76412 - for (rib = rn->info; rib; rib = rib->next)
76414 - if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED))
76415 - continue;
76417 - if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
76418 - break;
76421 - if (rib)
76423 - /* Same distance static route is there. Update it with new
76424 - nexthop. */
76425 - route_unlock_node (rn);
76427 - switch (si->type)
76429 - case STATIC_IPV6_GATEWAY:
76430 - nexthop_ipv6_add (rib, &si->ipv6);
76431 - break;
76432 - case STATIC_IPV6_IFNAME:
76433 - nexthop_ifname_add (rib, si->ifname);
76434 - break;
76435 - case STATIC_IPV6_GATEWAY_IFNAME:
76436 - nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
76437 - break;
76439 - rib_queue_add (&zebrad, rn);
76441 - else
76443 - /* This is new static route. */
76444 - rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
76446 - rib->type = ZEBRA_ROUTE_STATIC;
76447 - rib->distance = si->distance;
76448 - rib->metric = 0;
76449 - rib->nexthop_num = 0;
76451 - switch (si->type)
76453 - case STATIC_IPV6_GATEWAY:
76454 - nexthop_ipv6_add (rib, &si->ipv6);
76455 - break;
76456 - case STATIC_IPV6_IFNAME:
76457 - nexthop_ifname_add (rib, si->ifname);
76458 - break;
76459 - case STATIC_IPV6_GATEWAY_IFNAME:
76460 - nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname);
76461 - break;
76464 - /* Save the flags of this static routes (reject, blackhole) */
76465 - rib->flags = si->flags;
76467 - /* Link this rib to the tree. */
76468 - rib_addnode (rn, rib);
76472 -static int
76473 -static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si)
76475 - if (nexthop->type == NEXTHOP_TYPE_IPV6
76476 - && si->type == STATIC_IPV6_GATEWAY
76477 - && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6))
76478 - return 1;
76479 - if (nexthop->type == NEXTHOP_TYPE_IFNAME
76480 - && si->type == STATIC_IPV6_IFNAME
76481 - && strcmp (nexthop->ifname, si->ifname) == 0)
76482 - return 1;
76483 - if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
76484 - && si->type == STATIC_IPV6_GATEWAY_IFNAME
76485 - && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)
76486 - && strcmp (nexthop->ifname, si->ifname) == 0)
76487 - return 1;
76488 - return 0;
76491 -static void
76492 -static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
76494 - struct route_table *table;
76495 - struct route_node *rn;
76496 - struct rib *rib;
76497 - struct nexthop *nexthop;
76499 - /* Lookup table. */
76500 - table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
76501 - if (! table)
76502 - return;
76504 - /* Lookup existing route with type and distance. */
76505 - rn = route_node_lookup (table, (struct prefix *) p);
76506 - if (! rn)
76507 - return;
76509 - for (rib = rn->info; rib; rib = rib->next)
76511 - if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
76512 - continue;
76514 - if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance)
76515 - break;
76518 - if (! rib)
76520 - route_unlock_node (rn);
76521 - return;
76524 - /* Lookup nexthop. */
76525 - for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
76526 - if (static_ipv6_nexthop_same (nexthop, si))
76527 - break;
76529 - /* Can't find nexthop. */
76530 - if (! nexthop)
76532 - route_unlock_node (rn);
76533 - return;
76536 - /* Check nexthop. */
76537 - if (rib->nexthop_num == 1)
76539 - rib_delnode (rn, rib);
76541 - else
76543 - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
76544 - rib_uninstall (rn, rib);
76545 - nexthop_delete (rib, nexthop);
76546 - nexthop_free (nexthop);
76547 - rib_queue_add (&zebrad, rn);
76549 - /* Unlock node. */
76550 - route_unlock_node (rn);
76553 -/* Add static route into static route configuration. */
76554 -int
76555 -static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
76556 - const char *ifname, u_char flags, u_char distance,
76557 - u_int32_t vrf_id)
76559 - struct route_node *rn;
76560 - struct static_ipv6 *si;
76561 - struct static_ipv6 *pp;
76562 - struct static_ipv6 *cp;
76563 - struct route_table *stable;
76565 - /* Lookup table. */
76566 - stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
76567 - if (! stable)
76568 - return -1;
76570 - if (!gate &&
76571 - (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFNAME))
76572 - return -1;
76574 - if (!ifname &&
76575 - (type == STATIC_IPV6_GATEWAY_IFNAME || type == STATIC_IPV6_IFNAME))
76576 - return -1;
76578 - /* Lookup static route prefix. */
76579 - rn = route_node_get (stable, p);
76581 - /* Do nothing if there is a same static route. */
76582 - for (si = rn->info; si; si = si->next)
76584 - if (distance == si->distance
76585 - && type == si->type
76586 - && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
76587 - && (! ifname || strcmp (ifname, si->ifname) == 0))
76589 - route_unlock_node (rn);
76590 - return 0;
76594 - /* Make new static route structure. */
76595 - si = XMALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
76596 - memset (si, 0, sizeof (struct static_ipv6));
76598 - si->type = type;
76599 - si->distance = distance;
76600 - si->flags = flags;
76602 - switch (type)
76604 - case STATIC_IPV6_GATEWAY:
76605 - si->ipv6 = *gate;
76606 - break;
76607 - case STATIC_IPV6_IFNAME:
76608 - si->ifname = XSTRDUP (0, ifname);
76609 - break;
76610 - case STATIC_IPV6_GATEWAY_IFNAME:
76611 - si->ipv6 = *gate;
76612 - si->ifname = XSTRDUP (0, ifname);
76613 - break;
76616 - /* Add new static route information to the tree with sort by
76617 - distance value and gateway address. */
76618 - for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next)
76620 - if (si->distance < cp->distance)
76621 - break;
76622 - if (si->distance > cp->distance)
76623 - continue;
76626 - /* Make linked list. */
76627 - if (pp)
76628 - pp->next = si;
76629 - else
76630 - rn->info = si;
76631 - if (cp)
76632 - cp->prev = si;
76633 - si->prev = pp;
76634 - si->next = cp;
76636 - /* Install into rib. */
76637 - static_install_ipv6 (p, si);
76639 - return 1;
76642 -/* Delete static route from static route configuration. */
76643 -int
76644 -static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
76645 - const char *ifname, u_char distance, u_int32_t vrf_id)
76647 - struct route_node *rn;
76648 - struct static_ipv6 *si;
76649 - struct route_table *stable;
76651 - /* Lookup table. */
76652 - stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
76653 - if (! stable)
76654 - return -1;
76656 - /* Lookup static route prefix. */
76657 - rn = route_node_lookup (stable, p);
76658 - if (! rn)
76659 - return 0;
76661 - /* Find same static route is the tree */
76662 - for (si = rn->info; si; si = si->next)
76663 - if (distance == si->distance
76664 - && type == si->type
76665 - && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6))
76666 - && (! ifname || strcmp (ifname, si->ifname) == 0))
76667 - break;
76669 - /* Can't find static route. */
76670 - if (! si)
76672 - route_unlock_node (rn);
76673 - return 0;
76676 - /* Install into rib. */
76677 - static_uninstall_ipv6 (p, si);
76679 - /* Unlink static route from linked list. */
76680 - if (si->prev)
76681 - si->prev->next = si->next;
76682 - else
76683 - rn->info = si->next;
76684 - if (si->next)
76685 - si->next->prev = si->prev;
76687 - /* Free static route configuration. */
76688 - if (ifname)
76689 - XFREE (0, si->ifname);
76690 - XFREE (MTYPE_STATIC_IPV6, si);
76692 - return 1;
76694 #endif /* HAVE_IPV6 */
76696 /* RIB update function. */
76697 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/zebra_routemap.c quagga-mpls/zebra/zebra_routemap.c
76698 --- quagga/zebra/zebra_routemap.c 2007-06-14 05:02:14.000000000 -0500
76699 +++ quagga-mpls/zebra/zebra_routemap.c 2008-02-19 22:55:08.000000000 -0600
76700 @@ -419,25 +419,24 @@
76701 if (type == RMAP_ZEBRA)
76703 nexthop = object;
76704 - switch (nexthop->type) {
76705 - case NEXTHOP_TYPE_IFINDEX:
76706 - case NEXTHOP_TYPE_IFNAME:
76707 - case NEXTHOP_TYPE_IPV4_IFINDEX:
76708 - case NEXTHOP_TYPE_IPV4_IFNAME:
76709 - if (nexthop->rtype != NEXTHOP_TYPE_IPV4)
76710 - return RMAP_NOMATCH;
76711 - p.family = AF_INET;
76712 - p.prefix = nexthop->rgate.ipv4;
76713 - p.prefixlen = IPV4_MAX_BITLEN;
76714 - break;
76715 - case NEXTHOP_TYPE_IPV4:
76716 - p.family = AF_INET;
76717 - p.prefix = nexthop->gate.ipv4;
76718 - p.prefixlen = IPV4_MAX_BITLEN;
76719 - break;
76720 - default:
76721 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV4))
76723 + p.family = AF_INET;
76724 + p.prefix = nexthop->gate.ipv4;
76725 + p.prefixlen = IPV4_MAX_BITLEN;
76727 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX) ||
76728 + CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFNAME))
76730 + if (!CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV4))
76731 + return RMAP_NOMATCH;
76732 + p.family = AF_INET;
76733 + p.prefix = nexthop->rgate.ipv4;
76734 + p.prefixlen = IPV4_MAX_BITLEN;
76736 + else
76737 return RMAP_NOMATCH;
76740 alist = access_list_lookup (AFI_IP, (char *) rule);
76741 if (alist == NULL)
76742 return RMAP_NOMATCH;
76743 @@ -485,25 +484,24 @@
76744 if (type == RMAP_ZEBRA)
76746 nexthop = object;
76747 - switch (nexthop->type) {
76748 - case NEXTHOP_TYPE_IFINDEX:
76749 - case NEXTHOP_TYPE_IFNAME:
76750 - case NEXTHOP_TYPE_IPV4_IFINDEX:
76751 - case NEXTHOP_TYPE_IPV4_IFNAME:
76752 - if (nexthop->rtype != NEXTHOP_TYPE_IPV4)
76753 - return RMAP_NOMATCH;
76754 - p.family = AF_INET;
76755 - p.prefix = nexthop->rgate.ipv4;
76756 - p.prefixlen = IPV4_MAX_BITLEN;
76757 - break;
76758 - case NEXTHOP_TYPE_IPV4:
76759 - p.family = AF_INET;
76760 - p.prefix = nexthop->gate.ipv4;
76761 - p.prefixlen = IPV4_MAX_BITLEN;
76762 - break;
76763 - default:
76764 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV4))
76766 + p.family = AF_INET;
76767 + p.prefix = nexthop->gate.ipv4;
76768 + p.prefixlen = IPV4_MAX_BITLEN;
76770 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX) ||
76771 + CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFNAME))
76773 + if (!CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV4))
76774 + return RMAP_NOMATCH;
76775 + p.family = AF_INET;
76776 + p.prefix = nexthop->rgate.ipv4;
76777 + p.prefixlen = IPV4_MAX_BITLEN;
76779 + else
76780 return RMAP_NOMATCH;
76783 plist = prefix_list_lookup (AFI_IP, (char *) rule);
76784 if (plist == NULL)
76785 return RMAP_NOMATCH;
76786 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/zebra_snmp.c quagga-mpls/zebra/zebra_snmp.c
76787 --- quagga/zebra/zebra_snmp.c 2004-10-13 13:45:08.000000000 -0500
76788 +++ quagga-mpls/zebra/zebra_snmp.c 2006-08-09 22:03:15.000000000 -0500
76789 @@ -483,8 +483,7 @@
76790 return (u_char *)&nexthop->ifindex;
76791 break;
76792 case IPFORWARDTYPE:
76793 - if (nexthop->type == NEXTHOP_TYPE_IFINDEX
76794 - || nexthop->type == NEXTHOP_TYPE_IFNAME)
76795 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX))
76796 result = 3;
76797 else
76798 result = 4;
76799 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/zebra_vty.c quagga-mpls/zebra/zebra_vty.c
76800 --- quagga/zebra/zebra_vty.c 2007-06-14 05:02:15.000000000 -0500
76801 +++ quagga-mpls/zebra/zebra_vty.c 2008-02-22 21:42:25.000000000 -0600
76802 @@ -29,20 +29,25 @@
76803 #include "rib.h"
76805 #include "zebra/zserv.h"
76806 +#ifdef HAVE_MPLS
76807 +#include "mpls_vty.h"
76808 +#endif
76810 /* General fucntion for static route. */
76811 static int
76812 -zebra_static_ipv4 (struct vty *vty, int add_cmd, const char *dest_str,
76813 - const char *mask_str, const char *gate_str,
76814 - const char *flag_str, const char *distance_str)
76815 +do_zebra_static_ipv4 (struct vty *vty, int add_cmd, const char *dest_str,
76816 + const char *mask_str, const char *gate_str,
76817 + const char *flag_str, const char *distance_str,
76818 + const char *advmss_str, u_int mpls)
76820 int ret;
76821 u_char distance;
76822 struct prefix p;
76823 + struct zapi_nexthop nexthop;
76824 struct in_addr gate;
76825 struct in_addr mask;
76826 - const char *ifname;
76827 - u_char flag = 0;
76829 + memset(&nexthop, 0, sizeof (struct zapi_nexthop));
76831 ret = str2prefix (dest_str, &p);
76832 if (ret <= 0)
76833 @@ -72,6 +77,33 @@
76834 else
76835 distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
76837 + if (advmss_str)
76838 + nexthop.advmss = atoi (advmss_str);
76840 +#ifdef HAVE_MPLS
76841 + if (mpls)
76843 + struct zmpls_out_segment* out = mpls_out_segment_find(mpls);
76844 + if (out)
76846 + /* there needs to be a better way to do this, this is frought with
76847 + * possible inconsistency issues. By the time we get here we've
76848 + * created a out segment which has a full next hop specification,
76849 + * and we've started to build a whole new next hop in this
76850 + * function, are we sure they even match? Maybe static needs to
76851 + * creating the out segment and pass around a label struct
76852 + * and then we build a single nexthop which can be used to
76853 + * build the out segment and the static route entry.
76855 + * for now I punt, just copy the label from the out segment, we'll
76856 + * magically hook this back together someplace down the line ...
76857 + */
76858 + SET_FLAG (nexthop.type, ZEBRA_NEXTHOP_MPLS);
76859 + nexthop.mpls = out->nh.mpls;
76862 +#endif
76864 /* Null0 static route. */
76865 if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
76867 @@ -80,10 +112,13 @@
76868 vty_out (vty, "%% can not have flag %s with Null0%s", flag_str, VTY_NEWLINE);
76869 return CMD_WARNING;
76871 + SET_FLAG (nexthop.type, ZEBRA_NEXTHOP_DROP);
76872 + nexthop.gw.drop = ZEBRA_DROP_NULL;
76874 if (add_cmd)
76875 - static_add_ipv4 (&p, NULL, NULL, ZEBRA_FLAG_BLACKHOLE, distance, 0);
76876 + static_add_route (&p, &nexthop, distance, 0);
76877 else
76878 - static_delete_ipv4 (&p, NULL, NULL, distance, 0);
76879 + static_delete_route (&p, &nexthop, distance, 0);
76880 return CMD_SUCCESS;
76883 @@ -92,11 +127,13 @@
76884 switch(flag_str[0]) {
76885 case 'r':
76886 case 'R': /* XXX */
76887 - SET_FLAG (flag, ZEBRA_FLAG_REJECT);
76888 + SET_FLAG (nexthop.type, ZEBRA_NEXTHOP_DROP);
76889 + nexthop.gw.drop = ZEBRA_DROP_REJECT;
76890 break;
76891 case 'b':
76892 case 'B': /* XXX */
76893 - SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
76894 + SET_FLAG (nexthop.type, ZEBRA_NEXTHOP_DROP);
76895 + nexthop.gw.drop = ZEBRA_DROP_BLACKHOLE;
76896 break;
76897 default:
76898 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
76899 @@ -107,9 +144,9 @@
76900 if (gate_str == NULL)
76902 if (add_cmd)
76903 - static_add_ipv4 (&p, NULL, NULL, flag, distance, 0);
76904 + static_add_route (&p, &nexthop, distance, 0);
76905 else
76906 - static_delete_ipv4 (&p, NULL, NULL, distance, 0);
76907 + static_delete_route (&p, &nexthop, distance, 0);
76909 return CMD_SUCCESS;
76911 @@ -118,18 +155,34 @@
76912 address other case gate is treated as interface name. */
76913 ret = inet_aton (gate_str, &gate);
76914 if (ret)
76915 - ifname = NULL;
76917 + nexthop.gw.ipv4 = gate;
76918 + SET_FLAG (nexthop.type, ZEBRA_NEXTHOP_IPV4);
76920 else
76921 - ifname = gate_str;
76923 + strncpy(nexthop.intf.name, gate_str, IFNAMSIZ);
76924 + SET_FLAG (nexthop.type, ZEBRA_NEXTHOP_IFNAME);
76927 if (add_cmd)
76928 - static_add_ipv4 (&p, ifname ? NULL : &gate, ifname, flag, distance, 0);
76929 + static_add_route (&p, &nexthop, distance, 0);
76930 else
76931 - static_delete_ipv4 (&p, ifname ? NULL : &gate, ifname, distance, 0);
76932 + static_delete_route (&p, &nexthop, distance, 0);
76934 return CMD_SUCCESS;
76937 +int
76938 +zebra_static_ipv4 (struct vty *vty, int add_cmd, const char *dest_str,
76939 + const char *mask_str, const char *gate_str,
76940 + const char *flag_str, const char *distance_str,
76941 + const char *advmss_str)
76943 + return do_zebra_static_ipv4(vty, add_cmd, dest_str, mask_str, gate_str,
76944 + flag_str, distance_str, advmss_str, 0);
76947 /* Static route configuration. */
76948 DEFUN (ip_route,
76949 ip_route_cmd,
76950 @@ -141,7 +194,22 @@
76951 "IP gateway interface name\n"
76952 "Null interface\n")
76954 - return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL);
76955 + return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL, NULL);
76958 +DEFUN (ip_route_advmss,
76959 + ip_route_advmss_cmd,
76960 + "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) advmss <0-65495>",
76961 + IP_STR
76962 + "Establish static routes\n"
76963 + "IP destination prefix (e.g. 10.0.0.0/8)\n"
76964 + "IP gateway address\n"
76965 + "IP gateway interface name\n"
76966 + "Null interface\n"
76967 + "Advertised MSS\n"
76968 + "Maximum TCP Segment Size\n")
76970 + return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL, argv[2]);
76973 DEFUN (ip_route_flags,
76974 @@ -155,7 +223,7 @@
76975 "Emit an ICMP unreachable when matched\n"
76976 "Silently discard pkts when matched\n")
76978 - return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], NULL);
76979 + return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], NULL, NULL);
76982 DEFUN (ip_route_flags2,
76983 @@ -167,7 +235,7 @@
76984 "Emit an ICMP unreachable when matched\n"
76985 "Silently discard pkts when matched\n")
76987 - return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], NULL);
76988 + return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], NULL, NULL);
76991 /* Mask as A.B.C.D format. */
76992 @@ -182,7 +250,23 @@
76993 "IP gateway interface name\n"
76994 "Null interface\n")
76996 - return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
76997 + return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, NULL);
77000 +DEFUN (ip_route_mask_advmss,
77001 + ip_route_mask_advmss_cmd,
77002 + "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) advmss <0-65495>",
77003 + IP_STR
77004 + "Establish static routes\n"
77005 + "IP destination prefix\n"
77006 + "IP destination prefix mask\n"
77007 + "IP gateway address\n"
77008 + "IP gateway interface name\n"
77009 + "Null interface\n"
77010 + "Advertised MSS\n"
77011 + "Maximum TCP Segment Size\n")
77013 + return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, argv[3]);
77016 DEFUN (ip_route_mask_flags,
77017 @@ -197,7 +281,7 @@
77018 "Emit an ICMP unreachable when matched\n"
77019 "Silently discard pkts when matched\n")
77021 - return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL);
77022 + return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL, NULL);
77025 DEFUN (ip_route_mask_flags2,
77026 @@ -210,7 +294,7 @@
77027 "Emit an ICMP unreachable when matched\n"
77028 "Silently discard pkts when matched\n")
77030 - return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], NULL);
77031 + return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], NULL, NULL);
77034 /* Distance option value. */
77035 @@ -225,7 +309,23 @@
77036 "Null interface\n"
77037 "Distance value for this route\n")
77039 - return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2]);
77040 + return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2], NULL);
77043 +DEFUN (ip_route_distance_advmss,
77044 + ip_route_distance_advmss_cmd,
77045 + "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255> advmss <0-65495>",
77046 + IP_STR
77047 + "Establish static routes\n"
77048 + "IP destination prefix (e.g. 10.0.0.0/8)\n"
77049 + "IP gateway address\n"
77050 + "IP gateway interface name\n"
77051 + "Null interface\n"
77052 + "Distance value for this route\n"
77053 + "Advertised MSS\n"
77054 + "Maximum TCP Segment Size\n")
77056 + return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2], argv[3]);
77059 DEFUN (ip_route_flags_distance,
77060 @@ -240,7 +340,7 @@
77061 "Silently discard pkts when matched\n"
77062 "Distance value for this route\n")
77064 - return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], argv[3]);
77065 + return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], argv[3], NULL);
77068 DEFUN (ip_route_flags_distance2,
77069 @@ -253,7 +353,7 @@
77070 "Silently discard pkts when matched\n"
77071 "Distance value for this route\n")
77073 - return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], argv[2]);
77074 + return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], argv[2], NULL);
77077 DEFUN (ip_route_mask_distance,
77078 @@ -268,7 +368,24 @@
77079 "Null interface\n"
77080 "Distance value for this route\n")
77082 - return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
77083 + return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], NULL);
77086 +DEFUN (ip_route_mask_distance_advmss,
77087 + ip_route_mask_distance_advmss_cmd,
77088 + "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255> advmss <0-65495>",
77089 + IP_STR
77090 + "Establish static routes\n"
77091 + "IP destination prefix\n"
77092 + "IP destination prefix mask\n"
77093 + "IP gateway address\n"
77094 + "IP gateway interface name\n"
77095 + "Null interface\n"
77096 + "Distance value for this route\n"
77097 + "Advertised MSS\n"
77098 + "Maximum TCP Segment Size\n")
77100 + return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], argv[4]);
77103 DEFUN (ip_route_mask_flags_distance,
77104 @@ -284,7 +401,7 @@
77105 "Emit an ICMP unreachable when matched\n"
77106 "Silently discard pkts when matched\n")
77108 - return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]);
77109 + return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4], NULL);
77112 DEFUN (ip_route_mask_flags_distance2,
77113 @@ -298,7 +415,7 @@
77114 "Emit an ICMP unreachable when matched\n"
77115 "Silently discard pkts when matched\n")
77117 - return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]);
77118 + return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3], NULL);
77121 DEFUN (no_ip_route,
77122 @@ -312,7 +429,23 @@
77123 "IP gateway interface name\n"
77124 "Null interface\n")
77126 - return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL);
77127 + return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL, NULL);
77130 +DEFUN (no_ip_route_advmss,
77131 + no_ip_route_advmss_cmd,
77132 + "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) advmss <0-65495>",
77133 + NO_STR
77134 + IP_STR
77135 + "Establish static routes\n"
77136 + "IP destination prefix (e.g. 10.0.0.0/8)\n"
77137 + "IP gateway address\n"
77138 + "IP gateway interface name\n"
77139 + "Null interface\n"
77140 + "Advertised MSS\n"
77141 + "Maximum TCP Segment Size\n")
77143 + return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL, argv[2]);
77146 ALIAS (no_ip_route,
77147 @@ -337,7 +470,7 @@
77148 "Emit an ICMP unreachable when matched\n"
77149 "Silently discard pkts when matched\n")
77151 - return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, NULL, NULL);
77152 + return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, NULL, NULL, NULL);
77155 DEFUN (no_ip_route_mask,
77156 @@ -352,7 +485,24 @@
77157 "IP gateway interface name\n"
77158 "Null interface\n")
77160 - return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
77161 + return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, NULL);
77164 +DEFUN (no_ip_route_mask_advmss,
77165 + no_ip_route_mask_advmss_cmd,
77166 + "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) advmss <0-65495>",
77167 + NO_STR
77168 + IP_STR
77169 + "Establish static routes\n"
77170 + "IP destination prefix\n"
77171 + "IP destination prefix mask\n"
77172 + "IP gateway address\n"
77173 + "IP gateway interface name\n"
77174 + "Null interface\n"
77175 + "Advertised MSS\n"
77176 + "Maximum TCP Segment Size\n")
77178 + return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, argv[3]);
77181 ALIAS (no_ip_route_mask,
77182 @@ -379,7 +529,7 @@
77183 "Emit an ICMP unreachable when matched\n"
77184 "Silently discard pkts when matched\n")
77186 - return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
77187 + return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, NULL, NULL, NULL);
77190 DEFUN (no_ip_route_distance,
77191 @@ -394,7 +544,24 @@
77192 "Null interface\n"
77193 "Distance value for this route\n")
77195 - return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, argv[2]);
77196 + return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, argv[2], NULL);
77199 +DEFUN (no_ip_route_distance_advmss,
77200 + no_ip_route_distance_advmss_cmd,
77201 + "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255> advmss <0-65495>",
77202 + NO_STR
77203 + IP_STR
77204 + "Establish static routes\n"
77205 + "IP destination prefix (e.g. 10.0.0.0/8)\n"
77206 + "IP gateway address\n"
77207 + "IP gateway interface name\n"
77208 + "Null interface\n"
77209 + "Distance value for this route\n"
77210 + "Advertised MSS\n"
77211 + "Maximum TCP Segment Size\n")
77213 + return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, argv[2], argv[3]);
77216 DEFUN (no_ip_route_flags_distance,
77217 @@ -410,7 +577,7 @@
77218 "Silently discard pkts when matched\n"
77219 "Distance value for this route\n")
77221 - return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2], argv[3]);
77222 + return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2], argv[3], NULL);
77225 DEFUN (no_ip_route_flags_distance2,
77226 @@ -424,7 +591,7 @@
77227 "Silently discard pkts when matched\n"
77228 "Distance value for this route\n")
77230 - return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, argv[1], argv[2]);
77231 + return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, argv[1], argv[2], NULL);
77234 DEFUN (no_ip_route_mask_distance,
77235 @@ -440,7 +607,25 @@
77236 "Null interface\n"
77237 "Distance value for this route\n")
77239 - return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
77240 + return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], NULL);
77243 +DEFUN (no_ip_route_mask_distance_advmss,
77244 + no_ip_route_mask_distance_advmss_cmd,
77245 + "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255> advmss <0-65495>",
77246 + NO_STR
77247 + IP_STR
77248 + "Establish static routes\n"
77249 + "IP destination prefix\n"
77250 + "IP destination prefix mask\n"
77251 + "IP gateway address\n"
77252 + "IP gateway interface name\n"
77253 + "Null interface\n"
77254 + "Distance value for this route\n"
77255 + "Advertised MSS\n"
77256 + "Maximum TCP Segment Size\n")
77258 + return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], argv[4]);
77261 DEFUN (no_ip_route_mask_flags_distance,
77262 @@ -457,7 +642,7 @@
77263 "Silently discard pkts when matched\n"
77264 "Distance value for this route\n")
77266 - return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
77267 + return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4], NULL);
77270 DEFUN (no_ip_route_mask_flags_distance2,
77271 @@ -472,7 +657,7 @@
77272 "Silently discard pkts when matched\n"
77273 "Distance value for this route\n")
77275 - return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]);
77276 + return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3], NULL);
77279 char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1]; /* "any" == ZEBRA_ROUTE_MAX */
77280 @@ -527,6 +712,474 @@
77281 proto_rm[AFI_IP][i] = NULL;
77282 return CMD_SUCCESS;
77284 +#ifdef HAVE_MPLS
77285 +/* Static route + MPLS configuration. */
77286 +static int
77287 +zebra_static_ipv4_mpls (struct vty *vty, int add_cmd, const char *dest_str,
77288 + const char *addr, const char *mask_str, const char *distance,
77289 + const char *advmss, const char **argv)
77291 + struct zmpls_out_segment out;
77292 + struct zmpls_ftn *old;
77293 + struct zmpls_ftn ftn;
77294 + struct prefix p;
77295 + int result;
77297 + if (str2prefix (dest_str, &p) <= 0)
77299 + vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
77300 + return CMD_WARNING;
77303 + /* Cisco like mask notation. */
77304 + if (mask_str)
77306 + struct in_addr mask;
77307 + if (inet_aton (mask_str, &mask) == 0)
77309 + vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
77310 + return CMD_WARNING;
77312 + p.prefixlen = ip_masklen (mask);
77315 + /* Apply mask for given prefix. */
77316 + apply_mask (&p);
77318 + memcpy(&ftn.fec.u.p, &p, sizeof(p));
77319 + ftn.fec.type = ZEBRA_MPLS_FEC_IPV4;
77320 + ftn.fec.owner = ZEBRA_ROUTE_STATIC;
77321 + old = mpls_ftn_find_by_fec(&ftn.fec);
77323 + memset (&out, 0, sizeof (out));
77324 + out.owner = ZEBRA_ROUTE_STATIC;
77325 + result = nhlfe_parse (vty, argv, &out, addr);
77326 + if (result != CMD_SUCCESS)
77327 + return result;
77329 + out.index = mpls_out_segment_find_index_by_nhlfe(&out);
77331 + if (add_cmd)
77333 + if (old)
77335 + vty_out(vty, "FTN already exists%s",VTY_NEWLINE);
77336 + return CMD_WARNING;
77339 + if (out.index)
77341 + vty_out(vty, "NHLFE already exists%s",VTY_NEWLINE);
77342 + return CMD_WARNING;
77345 + if ((result = mpls_out_segment_register (&out)))
77347 + vty_out(vty, "Unable to register NHLFE(%d)%s", result, VTY_NEWLINE);
77348 + return CMD_WARNING;
77350 + ftn.out_index = out.index;
77352 + } else {
77353 + if (!out.index)
77355 + vty_out(vty, "No such NHLFE%s",VTY_NEWLINE);
77356 + return CMD_WARNING;
77359 + if (!old)
77361 + vty_out(vty, "No such FEC%s",VTY_NEWLINE);
77362 + return CMD_WARNING;
77365 + mpls_ftn_unregister(old, 0);
77368 + result = do_zebra_static_ipv4 (vty, add_cmd, dest_str, mask_str, addr, NULL,
77369 + distance, advmss, out.index);
77371 + if (add_cmd)
77373 + if (result != CMD_SUCCESS)
77375 + mpls_out_segment_unregister_by_index (out.index);
77376 + return CMD_WARNING;
77378 + mpls_ftn_register(&ftn, 0);
77380 + else
77382 + mpls_out_segment_unregister_by_index (out.index);
77384 + return CMD_SUCCESS;
77387 +DEFUN (ip_route_mpls,
77388 + ip_route_mpls_cmd,
77389 + "ip route A.B.C.D/M (gen|atm|fr) VALUE nexthop INTERFACE",
77390 + IP_STR
77391 + "Establish static routes\n"
77392 + "IP destination prefix (e.g. 10.0.0.0/8)\n"
77393 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77394 + "Out-going ATM MPLS label (VPI/VCI)\n"
77395 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77396 + "Out-going label value\n"
77397 + "Nexthop\n"
77398 + "IP gateway interface name\n")
77400 + return zebra_static_ipv4_mpls (vty, 1, argv[0], NULL, NULL, NULL, NULL, &argv[1]);
77403 +DEFUN (ip_route_mpls_advmss,
77404 + ip_route_mpls_advmss_cmd,
77405 + "ip route A.B.C.D/M (gen|atm|fr) VALUE nexthop INTERFACE advmss <0-65495>",
77406 + IP_STR
77407 + "Establish static routes\n"
77408 + "IP destination prefix (e.g. 10.0.0.0/8)\n"
77409 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77410 + "Out-going ATM MPLS label (VPI/VCI)\n"
77411 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77412 + "Out-going label value\n"
77413 + "Nexthop\n"
77414 + "IP gateway interface name\n"
77415 + "Advertised MSS\n"
77416 + "Maximum TCP Segment Size\n")
77418 + return zebra_static_ipv4_mpls (vty, 1, argv[0], NULL, NULL, NULL, argv[4], &argv[1]);
77421 +DEFUN (ip_route_mpls_addr,
77422 + ip_route_mpls_addr_cmd,
77423 + "ip route A.B.C.D/M (gen|atm|fr) VALUE nexthop INTERFACE ADDR",
77424 + IP_STR
77425 + "Establish static routes\n"
77426 + "IP destination prefix (e.g. 10.0.0.0/8)\n"
77427 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77428 + "Out-going ATM MPLS label (VPI/VCI)\n"
77429 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77430 + "Out-going label value\n"
77431 + "Nexthop\n"
77432 + "IP gateway interface name\n"
77433 + "IP gateway address\n")
77435 + return zebra_static_ipv4_mpls (vty, 1, argv[0], argv[4], NULL, NULL, NULL, &argv[1]);
77438 +DEFUN (ip_route_mpls_addr_advmss,
77439 + ip_route_mpls_addr_advmss_cmd,
77440 + "ip route A.B.C.D/M (gen|atm|fr) VALUE nexthop INTERFACE ADDR advmss <0-65495>",
77441 + IP_STR
77442 + "Establish static routes\n"
77443 + "IP destination prefix (e.g. 10.0.0.0/8)\n"
77444 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77445 + "Out-going ATM MPLS label (VPI/VCI)\n"
77446 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77447 + "Out-going label value\n"
77448 + "Nexthop\n"
77449 + "IP gateway interface name\n"
77450 + "IP gateway address\n"
77451 + "Advertised MSS\n"
77452 + "Maximum TCP Segment Size\n")
77454 + return zebra_static_ipv4_mpls (vty, 1, argv[0], argv[4], NULL, NULL, argv[5], &argv[1]);
77457 +/* Mask as A.B.C.D format. */
77458 +DEFUN (ip_route_mpls_mask,
77459 + ip_route_mpls_mask_cmd,
77460 + "ip route A.B.C.D A.B.C.D (gen|atm|fr) VALUE nexthop INTERFACE",
77461 + IP_STR
77462 + "Establish static routes\n"
77463 + "IP destination prefix\n"
77464 + "IP destination prefix mask\n"
77465 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77466 + "Out-going ATM MPLS label (VPI/VCI)\n"
77467 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77468 + "Out-going label value\n"
77469 + "Nexthop\n"
77470 + "IP gateway interface name\n")
77472 + return zebra_static_ipv4_mpls (vty, 1, argv[0], argv[1], NULL, NULL, NULL, &argv[2]);
77475 +DEFUN (ip_route_mpls_mask_addr,
77476 + ip_route_mpls_mask_addr_cmd,
77477 + "ip route A.B.C.D A.B.C.D (gen|atm|fr) VALUE nexthop INTERFACE ADDR",
77478 + IP_STR
77479 + "Establish static routes\n"
77480 + "IP destination prefix\n"
77481 + "IP destination prefix mask\n"
77482 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77483 + "Out-going ATM MPLS label (VPI/VCI)\n"
77484 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77485 + "Out-going label value\n"
77486 + "Nexthop\n"
77487 + "IP gateway interface name\n"
77488 + "IP gateway address\n")
77490 + return zebra_static_ipv4_mpls (vty, 1, argv[0], argv[1], argv[5], NULL, NULL, &argv[2]);
77493 +/* Distance option value. */
77494 +DEFUN (ip_route_mpls_distance,
77495 + ip_route_mpls_distance_cmd,
77496 + "ip route A.B.C.D/M (gen|atm|fr) VALUE nexthop INTERFACE <1-255>",
77497 + IP_STR
77498 + "Establish static routes\n"
77499 + "IP destination prefix (e.g. 10.0.0.0/8)\n"
77500 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77501 + "Out-going ATM MPLS label (VPI/VCI)\n"
77502 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77503 + "Out-going label value\n"
77504 + "Nexthop\n"
77505 + "IP gateway interface name\n"
77506 + "Distance value for this route\n")
77508 + return zebra_static_ipv4_mpls (vty, 1, argv[0], NULL, NULL, argv[4], NULL, &argv[1]);
77511 +DEFUN (ip_route_mpls_distance_addr,
77512 + ip_route_mpls_distance_addr_cmd,
77513 + "ip route A.B.C.D/M (gen|atm|fr) VALUE nexthop INTERFACE ADDR <1-255>",
77514 + IP_STR
77515 + "Establish static routes\n"
77516 + "IP destination prefix (e.g. 10.0.0.0/8)\n"
77517 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77518 + "Out-going ATM MPLS label (VPI/VCI)\n"
77519 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77520 + "Out-going label value\n"
77521 + "Nexthop\n"
77522 + "IP gateway interface name\n"
77523 + "IP gateway address\n"
77524 + "Distance value for this route\n")
77526 + return zebra_static_ipv4_mpls (vty, 1, argv[0], NULL, argv[4], argv[5], NULL, &argv[1]);
77529 +DEFUN (ip_route_mpls_mask_distance,
77530 + ip_route_mpls_mask_distance_cmd,
77531 + "ip route A.B.C.D A.B.C.D (gen|atm|fr) VALUE nexthop INTERFACE <1-255>",
77532 + IP_STR
77533 + "Establish static routes\n"
77534 + "IP destination prefix\n"
77535 + "IP destination prefix mask\n"
77536 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77537 + "Out-going ATM MPLS label (VPI/VCI)\n"
77538 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77539 + "Out-going label value\n"
77540 + "Nexthop\n"
77541 + "IP gateway interface name\n"
77542 + "Distance value for this route\n")
77544 + return zebra_static_ipv4_mpls (vty, 1, argv[0], argv[1], NULL, argv[5], NULL, &argv[2]);
77547 +DEFUN (ip_route_mpls_mask_distance_addr,
77548 + ip_route_mpls_mask_distance_addr_cmd,
77549 + "ip route A.B.C.D A.B.C.D (gen|atm|fr) VALUE nexthop INTERFACE ADDR <1-255>",
77550 + IP_STR
77551 + "Establish static routes\n"
77552 + "IP destination prefix\n"
77553 + "IP destination prefix mask\n"
77554 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77555 + "Out-going ATM MPLS label (VPI/VCI)\n"
77556 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77557 + "Out-going label value\n"
77558 + "Nexthop\n"
77559 + "IP gateway interface name\n"
77560 + "IP gateway address\n"
77561 + "Distance value for this route\n")
77563 + return zebra_static_ipv4_mpls (vty, 1, argv[0], argv[1], argv[5], argv[6], NULL, &argv[2]);
77566 +DEFUN (no_ip_route_mpls,
77567 + no_ip_route_mpls_cmd,
77568 + "no ip route A.B.C.D/M (gen|atm|fr) VALUE nexthop INTERFACE",
77569 + NO_STR
77570 + IP_STR
77571 + "Establish static routes\n"
77572 + "IP destination prefix (e.g. 10.0.0.0/8)\n"
77573 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77574 + "Out-going ATM MPLS label (VPI/VCI)\n"
77575 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77576 + "Out-going label value\n"
77577 + "Nexthop\n"
77578 + "IP gateway interface name\n")
77580 + return zebra_static_ipv4_mpls (vty, 0, argv[0], NULL, NULL, NULL, NULL, &argv[1]);
77583 +DEFUN (no_ip_route_mpls_advmss,
77584 + no_ip_route_mpls_advmss_cmd,
77585 + "no ip route A.B.C.D/M (gen|atm|fr) VALUE nexthop INTERFACE advmss <0-65495>",
77586 + NO_STR
77587 + IP_STR
77588 + "Establish static routes\n"
77589 + "IP destination prefix (e.g. 10.0.0.0/8)\n"
77590 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77591 + "Out-going ATM MPLS label (VPI/VCI)\n"
77592 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77593 + "Out-going label value\n"
77594 + "Nexthop\n"
77595 + "IP gateway interface name\n"
77596 + "Advertised MSS\n"
77597 + "Maximum TCP Segment Size\n")
77599 + return zebra_static_ipv4_mpls (vty, 0, argv[0], NULL, NULL, NULL, argv[4], &argv[1]);
77601 +DEFUN (no_ip_route_mpls_addr,
77602 + no_ip_route_mpls_addr_cmd,
77603 + "no ip route A.B.C.D/M (gen|atm|fr) VALUE nexthop INTERFACE ADDR",
77604 + NO_STR
77605 + IP_STR
77606 + "Establish static routes\n"
77607 + "IP destination prefix (e.g. 10.0.0.0/8)\n"
77608 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77609 + "Out-going ATM MPLS label (VPI/VCI)\n"
77610 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77611 + "Out-going label value\n"
77612 + "Nexthop\n"
77613 + "IP gateway interface name\n"
77614 + "IP gateway address\n")
77616 + return zebra_static_ipv4_mpls (vty, 0, argv[0], argv[4], NULL, NULL, NULL, &argv[1]);
77619 +DEFUN (no_ip_route_mpls_addr_advmss,
77620 + no_ip_route_mpls_addr_advmss_cmd,
77621 + "no ip route A.B.C.D/M (gen|atm|fr) VALUE nexthop INTERFACE ADDR advmss <0-65495>",
77622 + NO_STR
77623 + IP_STR
77624 + "Establish static routes\n"
77625 + "IP destination prefix (e.g. 10.0.0.0/8)\n"
77626 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77627 + "Out-going ATM MPLS label (VPI/VCI)\n"
77628 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77629 + "Out-going label value\n"
77630 + "Nexthop\n"
77631 + "IP gateway interface name\n"
77632 + "IP gateway address\n"
77633 + "Advertised MSS\n"
77634 + "Maximum TCP Segment Size\n")
77636 + return zebra_static_ipv4_mpls (vty, 0, argv[0], argv[4], NULL, NULL, argv[5], &argv[1]);
77639 +DEFUN (no_ip_route_mpls_mask,
77640 + no_ip_route_mpls_mask_cmd,
77641 + "no ip route A.B.C.D A.B.C.D (gen|atm|fr) VALUE nexthop INTERFACE",
77642 + NO_STR
77643 + IP_STR
77644 + "Establish static routes\n"
77645 + "IP destination prefix\n"
77646 + "IP destination prefix mask\n"
77647 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77648 + "Out-going ATM MPLS label (VPI/VCI)\n"
77649 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77650 + "Out-going label value\n"
77651 + "Nexthop\n"
77652 + "IP gateway interface name\n")
77654 + return zebra_static_ipv4_mpls (vty, 0, argv[0], argv[1], NULL, NULL, NULL, &argv[2]);
77657 +DEFUN (no_ip_route_mpls_mask_addr,
77658 + no_ip_route_mpls_mask_addr_cmd,
77659 + "no ip route A.B.C.D A.B.C.D (gen|atm|fr) VALUE nexthop INTERFACE ADDR",
77660 + NO_STR
77661 + IP_STR
77662 + "Establish static routes\n"
77663 + "IP destination prefix\n"
77664 + "IP destination prefix mask\n"
77665 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77666 + "Out-going ATM MPLS label (VPI/VCI)\n"
77667 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77668 + "Out-going label value\n"
77669 + "Nexthop\n"
77670 + "IP gateway interface name\n"
77671 + "IP gateway address\n")
77673 + return zebra_static_ipv4_mpls (vty, 0, argv[0], argv[1], argv[5], NULL, NULL, &argv[2]);
77676 +DEFUN (no_ip_route_mpls_distance,
77677 + no_ip_route_mpls_distance_cmd,
77678 + "no ip route A.B.C.D/M (gen|atm|fr) VALUE nexthop INTERFACE <1-255>",
77679 + NO_STR
77680 + IP_STR
77681 + "Establish static routes\n"
77682 + "IP destination prefix (e.g. 10.0.0.0/8)\n"
77683 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77684 + "Out-going ATM MPLS label (VPI/VCI)\n"
77685 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77686 + "Out-going label value\n"
77687 + "Nexthop\n"
77688 + "IP gateway interface name\n"
77689 + "Distance value for this route\n")
77691 + return zebra_static_ipv4_mpls (vty, 0, argv[0], NULL, NULL, argv[4], NULL, &argv[1]);
77694 +DEFUN (no_ip_route_mpls_distance_addr,
77695 + no_ip_route_mpls_distance_addr_cmd,
77696 + "no ip route A.B.C.D/M (gen|atm|fr) VALUE nexthop INTERFACE ADDR <1-255>",
77697 + NO_STR
77698 + IP_STR
77699 + "Establish static routes\n"
77700 + "IP destination prefix (e.g. 10.0.0.0/8)\n"
77701 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77702 + "Out-going ATM MPLS label (VPI/VCI)\n"
77703 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77704 + "Out-going label value\n"
77705 + "Nexthop\n"
77706 + "IP gateway interface name\n"
77707 + "IP gateway address\n"
77708 + "Distance value for this route\n")
77710 + return zebra_static_ipv4_mpls (vty, 0, argv[0], NULL, argv[4], argv[5], NULL, &argv[1]);
77713 +DEFUN (no_ip_route_mpls_mask_distance,
77714 + no_ip_route_mpls_mask_distance_cmd,
77715 + "no ip route A.B.C.D A.B.C.D (gen|atm|fr) VALUE nexthop INTERFACE <1-255>",
77716 + NO_STR
77717 + IP_STR
77718 + "Establish static routes\n"
77719 + "IP destination prefix\n"
77720 + "IP destination prefix mask\n"
77721 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77722 + "Out-going ATM MPLS label (VPI/VCI)\n"
77723 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77724 + "Out-going label value\n"
77725 + "Nexthop\n"
77726 + "IP gateway interface name\n"
77727 + "Distance value for this route\n")
77729 + return zebra_static_ipv4_mpls (vty, 0, argv[0], argv[1], NULL, argv[5], NULL, &argv[2]);
77732 +DEFUN (no_ip_route_mpls_mask_distance_addr,
77733 + no_ip_route_mpls_mask_distance_addr_cmd,
77734 + "no ip route A.B.C.D A.B.C.D (gen|atm|fr) VALUE nexthop INTERFACE ADDR <1-255>",
77735 + NO_STR
77736 + IP_STR
77737 + "Establish static routes\n"
77738 + "IP destination prefix\n"
77739 + "IP destination prefix mask\n"
77740 + "Out-going generic MPLS label (16 - 2^20-1)\n"
77741 + "Out-going ATM MPLS label (VPI/VCI)\n"
77742 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
77743 + "Out-going label value\n"
77744 + "Nexthop\n"
77745 + "IP gateway interface name\n"
77746 + "IP gateway address\n"
77747 + "Distance value for this route\n")
77749 + return zebra_static_ipv4_mpls (vty, 0, argv[0], argv[1], argv[5], argv[6], NULL, &argv[2]);
77751 +#endif /* HAVE_MPLS */
77753 /* New RIB. Detailed information for IPv4 route. */
77754 static void
77755 @@ -584,31 +1237,83 @@
77756 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
77758 char addrstr[32];
77759 + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_IGNORE))
77760 + continue;
77762 + if (nexthop->advmss)
77763 + vty_out (vty, " advmss %d", nexthop->advmss);
77765 vty_out (vty, " %c",
77766 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
77768 - switch (nexthop->type)
77769 +#ifdef HAVE_IPV6
77770 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV6))
77772 + if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
77774 + if (inet_ntop(AF_INET6, &nexthop->src.ipv6, addrstr,
77775 + sizeof addrstr))
77776 + vty_out (vty, ", src %s", addrstr);
77779 + else
77780 +#endif /* HAVE_IPV6 */
77781 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV4))
77783 - case NEXTHOP_TYPE_IPV4:
77784 - case NEXTHOP_TYPE_IPV4_IFINDEX:
77785 vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4));
77786 - if (nexthop->ifindex)
77787 - vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
77788 - break;
77789 - case NEXTHOP_TYPE_IFINDEX:
77790 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFNAME))
77791 + vty_out (vty, ", via %s", nexthop->ifname);
77792 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX))
77793 + if (if_lookup_by_index(nexthop->ifindex))
77794 + vty_out (vty, ", via %s", ifindex2ifname(nexthop->ifindex));
77796 + if (nexthop->src.ipv4.s_addr)
77798 + if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr,
77799 + sizeof addrstr))
77800 + vty_out (vty, ", src %s", addrstr);
77803 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFNAME))
77805 + vty_out (vty, " directly connected, %s", nexthop->ifname);
77807 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX))
77809 vty_out (vty, " directly connected, %s",
77810 ifindex2ifname (nexthop->ifindex));
77811 - break;
77812 - case NEXTHOP_TYPE_IFNAME:
77813 - vty_out (vty, " directly connected, %s", nexthop->ifname);
77814 - break;
77815 - case NEXTHOP_TYPE_BLACKHOLE:
77816 - vty_out (vty, " directly connected, Null0");
77817 - break;
77818 - default:
77819 - break;
77821 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_DROP))
77823 + switch (nexthop->drop)
77825 + case ZEBRA_DROP_NULL:
77826 + vty_out (vty, " directly connected, Null0");
77827 + break;
77828 + case ZEBRA_DROP_REJECT:
77829 + vty_out (vty, ", reject");
77830 + break;
77831 + case ZEBRA_DROP_BLACKHOLE:
77832 + vty_out (vty, ", blackhole");
77833 + break;
77834 + default:
77835 + assert(0);
77838 +#ifdef HAVE_MPLS
77839 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_MPLS))
77841 + struct zmpls_out_segment *out;
77842 + char buf[16];
77844 + out = mpls_out_segment_find(nexthop->mpls);
77845 + if (out)
77846 + mpls_print_label(&out->nh.mpls, buf);
77847 + else
77848 + strcpy(buf, "not found");
77849 + vty_out (vty, " (label %s)", buf);
77851 +#endif
77852 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
77853 vty_out (vty, " inactive");
77855 @@ -616,48 +1321,48 @@
77857 vty_out (vty, " (recursive");
77859 - switch (nexthop->rtype)
77860 +#ifdef HAVE_IPV6
77861 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV6))
77863 + if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
77865 + if (inet_ntop(AF_INET6, &nexthop->src.ipv6, addrstr,
77866 + sizeof addrstr))
77867 + vty_out (vty, ", src %s", addrstr);
77870 + else
77871 +#endif /* HAVE_IPV6 */
77872 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV4))
77874 - case NEXTHOP_TYPE_IPV4:
77875 - case NEXTHOP_TYPE_IPV4_IFINDEX:
77876 vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
77877 - break;
77878 - case NEXTHOP_TYPE_IFINDEX:
77879 - case NEXTHOP_TYPE_IFNAME:
77880 + if (nexthop->src.ipv4.s_addr)
77882 + if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr,
77883 + sizeof addrstr))
77884 + vty_out (vty, ", src %s", addrstr);
77887 + else if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IFINDEX))
77889 vty_out (vty, " is directly connected, %s)",
77890 ifindex2ifname (nexthop->rifindex));
77891 - break;
77892 - default:
77893 - break;
77895 +#ifdef HAVE_MPLS
77896 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_MPLS))
77898 + struct zmpls_out_segment *out;
77899 + char buf[16];
77901 + out = mpls_out_segment_find(nexthop->rmpls);
77902 + if (out)
77903 + mpls_print_label(&out->nh.mpls, buf);
77904 + else
77905 + strcpy(buf, "not found");
77906 + vty_out (vty, " (label %s)", buf);
77908 +#endif
77910 - switch (nexthop->type)
77912 - case NEXTHOP_TYPE_IPV4:
77913 - case NEXTHOP_TYPE_IPV4_IFINDEX:
77914 - case NEXTHOP_TYPE_IPV4_IFNAME:
77915 - if (nexthop->src.ipv4.s_addr)
77917 - if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr,
77918 - sizeof addrstr))
77919 - vty_out (vty, ", src %s", addrstr);
77921 - break;
77922 -#ifdef HAVE_IPV6
77923 - case NEXTHOP_TYPE_IPV6:
77924 - case NEXTHOP_TYPE_IPV6_IFINDEX:
77925 - case NEXTHOP_TYPE_IPV6_IFNAME:
77926 - if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
77928 - if (inet_ntop(AF_INET6, &nexthop->src.ipv6, addrstr,
77929 - sizeof addrstr))
77930 - vty_out (vty, ", src %s", addrstr);
77932 - break;
77933 -#endif /* HAVE_IPV6 */
77934 - default:
77935 - break;
77937 vty_out (vty, "%s", VTY_NEWLINE);
77939 vty_out (vty, "%s", VTY_NEWLINE);
77940 @@ -674,6 +1379,9 @@
77941 /* Nexthop information. */
77942 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
77944 + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_IGNORE))
77945 + continue;
77947 if (nexthop == rib->nexthop)
77949 /* Prefix information. */
77950 @@ -698,27 +1406,72 @@
77951 ? '*' : ' ',
77952 len - 3, ' ');
77954 - switch (nexthop->type)
77955 +#ifdef HAVE_IPV6
77956 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV6))
77958 + if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
77960 + if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
77961 + vty_out (vty, ", src %s", buf);
77964 + else
77965 +#endif /* HAVE_IPV6 */
77966 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV4))
77968 - case NEXTHOP_TYPE_IPV4:
77969 - case NEXTHOP_TYPE_IPV4_IFINDEX:
77970 vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
77971 - if (nexthop->ifindex)
77972 - vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
77973 - break;
77974 - case NEXTHOP_TYPE_IFINDEX:
77975 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFNAME))
77976 + vty_out (vty, ", %s", nexthop->ifname);
77977 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX))
77978 + if (if_lookup_by_index(nexthop->ifindex))
77979 + vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
77981 + if (nexthop->src.ipv4.s_addr)
77983 + if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
77984 + vty_out (vty, ", src %s", buf);
77987 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFNAME))
77989 + vty_out (vty, " is directly connected, %s", nexthop->ifname);
77991 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX))
77993 vty_out (vty, " is directly connected, %s",
77994 ifindex2ifname (nexthop->ifindex));
77995 - break;
77996 - case NEXTHOP_TYPE_IFNAME:
77997 - vty_out (vty, " is directly connected, %s", nexthop->ifname);
77998 - break;
77999 - case NEXTHOP_TYPE_BLACKHOLE:
78000 - vty_out (vty, " is directly connected, Null0");
78001 - break;
78002 - default:
78003 - break;
78005 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_DROP))
78007 + switch (nexthop->drop)
78009 + case ZEBRA_DROP_NULL:
78010 + vty_out (vty, " directly connected, Null0");
78011 + break;
78012 + case ZEBRA_DROP_REJECT:
78013 + vty_out (vty, ", reject");
78014 + break;
78015 + case ZEBRA_DROP_BLACKHOLE:
78016 + vty_out (vty, ", blackhole");
78017 + break;
78018 + default:
78019 + assert(0);
78022 +#ifdef HAVE_MPLS
78023 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_MPLS))
78025 + struct zmpls_out_segment *out;
78026 + char buf[16];
78028 + out = mpls_out_segment_find(nexthop->mpls);
78029 + if (out)
78030 + mpls_print_label(&out->nh.mpls, buf);
78031 + else
78032 + strcpy(buf, "not found");
78033 + vty_out (vty, " (label %s)", buf);
78035 +#endif
78036 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
78037 vty_out (vty, " inactive");
78039 @@ -726,46 +1479,53 @@
78041 vty_out (vty, " (recursive");
78043 - switch (nexthop->rtype)
78044 +#ifdef HAVE_IPV6
78045 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV6))
78047 + if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
78049 + if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
78050 + vty_out (vty, ", src %s", buf);
78053 + else
78054 +#endif /* HAVE_IPV6 */
78055 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV4))
78057 + vty_out (vty, " via %s", inet_ntoa (nexthop->rgate.ipv4));
78058 + if (nexthop->rifindex)
78059 + vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
78060 + vty_out (vty, ")");
78062 + if (nexthop->src.ipv4.s_addr)
78064 + if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
78065 + vty_out (vty, ", src %s", buf);
78068 + else if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IFINDEX))
78070 - case NEXTHOP_TYPE_IPV4:
78071 - case NEXTHOP_TYPE_IPV4_IFINDEX:
78072 - vty_out (vty, " via %s)", inet_ntoa (nexthop->rgate.ipv4));
78073 - break;
78074 - case NEXTHOP_TYPE_IFINDEX:
78075 - case NEXTHOP_TYPE_IFNAME:
78076 vty_out (vty, " is directly connected, %s)",
78077 ifindex2ifname (nexthop->rifindex));
78078 - break;
78079 - default:
78080 - break;
78082 +#ifdef HAVE_MPLS
78083 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_MPLS))
78085 + struct zmpls_out_segment *out;
78086 + char buf[16];
78088 + out = mpls_out_segment_find(nexthop->rmpls);
78089 + if (out)
78090 + mpls_print_label(&out->nh.mpls, buf);
78091 + else
78092 + strcpy(buf, "not found");
78093 + vty_out (vty, " (label %s)", buf);
78095 +#endif
78097 - switch (nexthop->type)
78099 - case NEXTHOP_TYPE_IPV4:
78100 - case NEXTHOP_TYPE_IPV4_IFINDEX:
78101 - case NEXTHOP_TYPE_IPV4_IFNAME:
78102 - if (nexthop->src.ipv4.s_addr)
78104 - if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf))
78105 - vty_out (vty, ", src %s", buf);
78107 - break;
78108 -#ifdef HAVE_IPV6
78109 - case NEXTHOP_TYPE_IPV6:
78110 - case NEXTHOP_TYPE_IPV6_IFINDEX:
78111 - case NEXTHOP_TYPE_IPV6_IFNAME:
78112 - if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any))
78114 - if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf))
78115 - vty_out (vty, ", src %s", buf);
78117 - break;
78118 -#endif /* HAVE_IPV6 */
78119 - default:
78120 - break;
78123 + if (nexthop->advmss)
78124 + vty_out (vty, " advmss %d", nexthop->advmss);
78126 if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
78127 vty_out (vty, ", bh");
78128 @@ -954,6 +1714,8 @@
78129 type = ZEBRA_ROUTE_RIP;
78130 else if (strncmp (argv[0], "s", 1) == 0)
78131 type = ZEBRA_ROUTE_STATIC;
78132 + else if (strncmp (argv[0], "l", 1) == 0)
78133 + type = ZEBRA_ROUTE_LDP;
78134 else
78136 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
78137 @@ -1111,7 +1873,7 @@
78138 static_config_ipv4 (struct vty *vty)
78140 struct route_node *rn;
78141 - struct static_ipv4 *si;
78142 + struct static_route *si;
78143 struct route_table *stable;
78144 int write;
78146 @@ -1128,32 +1890,51 @@
78147 vty_out (vty, "ip route %s/%d", inet_ntoa (rn->p.u.prefix4),
78148 rn->p.prefixlen);
78150 - switch (si->type)
78152 - case STATIC_IPV4_GATEWAY:
78153 - vty_out (vty, " %s", inet_ntoa (si->gate.ipv4));
78154 - break;
78155 - case STATIC_IPV4_IFNAME:
78156 - vty_out (vty, " %s", si->gate.ifname);
78157 - break;
78158 - case STATIC_IPV4_BLACKHOLE:
78159 - vty_out (vty, " Null0");
78160 - break;
78162 + if (CHECK_FLAG(si->nh.type, ZEBRA_NEXTHOP_DROP))
78163 + switch(si->nh.gw.drop)
78165 + case ZEBRA_DROP_NULL:
78166 + vty_out (vty, " Null0");
78167 + break;
78168 + case ZEBRA_DROP_REJECT:
78169 + vty_out (vty, " %s", "reject");
78170 + break;
78171 + case ZEBRA_DROP_BLACKHOLE:
78172 + vty_out (vty, " %s", "blackhole");
78173 + break;
78174 + default:
78175 + assert(0);
78177 + else
78179 + if (CHECK_FLAG(si->nh.type, ZEBRA_NEXTHOP_IPV4))
78180 + vty_out (vty, " %s", inet_ntoa (si->nh.gw.ipv4));
78181 + if (CHECK_FLAG(si->nh.type, ZEBRA_NEXTHOP_IFNAME))
78182 + vty_out (vty, " %s", si->nh.intf.name);
78183 +#ifdef HAVE_MPLS
78184 + if (CHECK_FLAG(si->nh.type, ZEBRA_NEXTHOP_MPLS))
78186 + int index = mpls_out_segment_find_index_by_nexthop(&si->nh);
78187 + vty_out (vty, " ");
78188 + if (index)
78190 + mpls_out_segment_config_write (vty,
78191 + mpls_out_segment_find(index));
78193 + else
78195 + vty_out (vty, "(unknown)");
78198 +#endif
78201 - /* flags are incompatible with STATIC_IPV4_BLACKHOLE */
78202 - if (si->type != STATIC_IPV4_BLACKHOLE)
78204 - if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
78205 - vty_out (vty, " %s", "reject");
78207 - if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
78208 - vty_out (vty, " %s", "blackhole");
78211 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
78212 vty_out (vty, " %d", si->distance);
78214 + if (si->nh.advmss)
78215 + vty_out (vty, " advmss %d", si->nh.advmss);
78217 vty_out (vty, "%s", VTY_NEWLINE);
78219 write = 1;
78220 @@ -1201,11 +1982,11 @@
78221 int ret;
78222 u_char distance;
78223 struct prefix p;
78224 - struct in6_addr *gate = NULL;
78225 struct in6_addr gate_addr;
78226 - u_char type = 0;
78227 + struct zapi_nexthop nh;
78228 int table = 0;
78229 - u_char flag = 0;
78231 + memset(&nh, 0, sizeof(struct zapi_nexthop));
78233 ret = str2prefix (dest_str, &p);
78234 if (ret <= 0)
78235 @@ -1222,11 +2003,13 @@
78236 switch(flag_str[0]) {
78237 case 'r':
78238 case 'R': /* XXX */
78239 - SET_FLAG (flag, ZEBRA_FLAG_REJECT);
78240 + SET_FLAG (nh.type, ZEBRA_NEXTHOP_DROP);
78241 + nh.gw.drop = ZEBRA_DROP_REJECT;
78242 break;
78243 case 'b':
78244 case 'B': /* XXX */
78245 - SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE);
78246 + SET_FLAG (nh.type, ZEBRA_NEXTHOP_DROP);
78247 + nh.gw.drop = ZEBRA_DROP_BLACKHOLE;
78248 break;
78249 default:
78250 vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE);
78251 @@ -1253,27 +2036,30 @@
78252 vty_out (vty, "%% Malformed address%s", VTY_NEWLINE);
78253 return CMD_WARNING;
78255 - type = STATIC_IPV6_GATEWAY_IFNAME;
78256 - gate = &gate_addr;
78258 + SET_FLAG (nh.type, ZEBRA_NEXTHOP_IPV6);
78259 + SET_FLAG (nh.type, ZEBRA_NEXTHOP_IFNAME);
78260 + nh.gw.ipv6 = gate_addr;
78261 + strncpy(nh.intf.name, ifname, IFNAMSIZ);
78263 else
78265 if (ret == 1)
78267 - type = STATIC_IPV6_GATEWAY;
78268 - gate = &gate_addr;
78269 + SET_FLAG (nh.type, ZEBRA_NEXTHOP_IPV6);
78270 + nh.gw.ipv6 = gate_addr;
78272 else
78274 - type = STATIC_IPV6_IFNAME;
78275 - ifname = gate_str;
78276 + SET_FLAG (nh.type, ZEBRA_NEXTHOP_IFNAME);
78277 + strncpy(nh.intf.name, gate_str, IFNAMSIZ);
78281 if (add_cmd)
78282 - static_add_ipv6 (&p, type, gate, ifname, flag, distance, table);
78283 + static_add_route (&p, &nh, distance, table);
78284 else
78285 - static_delete_ipv6 (&p, type, gate, ifname, distance, table);
78286 + static_delete_route (&p, &nh, distance, table);
78288 return CMD_SUCCESS;
78290 @@ -1290,6 +2076,20 @@
78291 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL);
78294 +DEFUN (ipv6_route_advmss,
78295 + ipv6_route_advmss_cmd,
78296 + "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) advmss <0-65495>",
78297 + IP_STR
78298 + "Establish static routes\n"
78299 + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
78300 + "IPv6 gateway address\n"
78301 + "IPv6 gateway interface name\n"
78302 + "Advertised MSS\n"
78303 + "Maximum TCP Segment Size\n")
78305 + return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL);
78308 DEFUN (ipv6_route_flags,
78309 ipv6_route_flags_cmd,
78310 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
78311 @@ -1316,6 +2116,20 @@
78312 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
78315 +DEFUN (ipv6_route_ifname_advmss,
78316 + ipv6_route_ifname_advmss_cmd,
78317 + "ipv6 route X:X::X:X/M X:X::X:X INTERFACE advmss <0-65495>",
78318 + IP_STR
78319 + "Establish static routes\n"
78320 + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
78321 + "IPv6 gateway address\n"
78322 + "IPv6 gateway interface name\n"
78323 + "Advertised MSS\n"
78324 + "Maximum TCP Segment Size\n")
78326 + return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL);
78329 DEFUN (ipv6_route_ifname_flags,
78330 ipv6_route_ifname_flags_cmd,
78331 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
78332 @@ -1343,6 +2157,21 @@
78333 return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2]);
78336 +DEFUN (ipv6_route_pref_advmss,
78337 + ipv6_route_pref_advmss_cmd,
78338 + "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255> advmss <0-65495>",
78339 + IP_STR
78340 + "Establish static routes\n"
78341 + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
78342 + "IPv6 gateway address\n"
78343 + "IPv6 gateway interface name\n"
78344 + "Distance value for this prefix\n"
78345 + "Advertised MSS\n"
78346 + "Maximum TCP Segment Size\n")
78348 + return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2]);
78351 DEFUN (ipv6_route_flags_pref,
78352 ipv6_route_flags_pref_cmd,
78353 "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
78354 @@ -1371,6 +2200,21 @@
78355 return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
78358 +DEFUN (ipv6_route_ifname_pref_advmss,
78359 + ipv6_route_ifname_pref_advmss_cmd,
78360 + "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255> advmss <0-65495>",
78361 + IP_STR
78362 + "Establish static routes\n"
78363 + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
78364 + "IPv6 gateway address\n"
78365 + "IPv6 gateway interface name\n"
78366 + "Distance value for this prefix\n"
78367 + "Advertised MSS\n"
78368 + "Maximum TCP Segment Size\n")
78370 + return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]);
78373 DEFUN (ipv6_route_ifname_flags_pref,
78374 ipv6_route_ifname_flags_pref_cmd,
78375 "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
78376 @@ -1399,6 +2243,21 @@
78377 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
78380 +DEFUN (no_ipv6_route_advmss,
78381 + no_ipv6_route_advmss_cmd,
78382 + "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) advmss <0-65495>",
78383 + NO_STR
78384 + IP_STR
78385 + "Establish static routes\n"
78386 + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
78387 + "IPv6 gateway address\n"
78388 + "IPv6 gateway interface name\n"
78389 + "Advertised MSS\n"
78390 + "Maximum TCP Segment Size\n")
78392 + return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL);
78395 ALIAS (no_ipv6_route,
78396 no_ipv6_route_flags_cmd,
78397 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)",
78398 @@ -1424,6 +2283,21 @@
78399 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
78402 +DEFUN (no_ipv6_route_ifname_advmss,
78403 + no_ipv6_route_ifname_advmss_cmd,
78404 + "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE advmss <0-65495>",
78405 + NO_STR
78406 + IP_STR
78407 + "Establish static routes\n"
78408 + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
78409 + "IPv6 gateway address\n"
78410 + "IPv6 gateway interface name\n"
78411 + "Advertised MSS\n"
78412 + "Maximum TCP Segment Size\n")
78414 + return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL);
78417 ALIAS (no_ipv6_route_ifname,
78418 no_ipv6_route_ifname_flags_cmd,
78419 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)",
78420 @@ -1450,6 +2324,22 @@
78421 return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2]);
78424 +DEFUN (no_ipv6_route_pref_advmss,
78425 + no_ipv6_route_pref_advmss_cmd,
78426 + "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255> advmss <0-65495>",
78427 + NO_STR
78428 + IP_STR
78429 + "Establish static routes\n"
78430 + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
78431 + "IPv6 gateway address\n"
78432 + "IPv6 gateway interface name\n"
78433 + "Distance value for this prefix\n"
78434 + "Advertised MSS\n"
78435 + "Maximum TCP Segment Size\n")
78437 + return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2]);
78440 DEFUN (no_ipv6_route_flags_pref,
78441 no_ipv6_route_flags_pref_cmd,
78442 "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>",
78443 @@ -1481,6 +2371,22 @@
78444 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
78447 +DEFUN (no_ipv6_route_ifname_pref_advmss,
78448 + no_ipv6_route_ifname_pref_advmss_cmd,
78449 + "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255> advmss <0-65495>",
78450 + NO_STR
78451 + IP_STR
78452 + "Establish static routes\n"
78453 + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
78454 + "IPv6 gateway address\n"
78455 + "IPv6 gateway interface name\n"
78456 + "Distance value for this prefix\n"
78457 + "Advertised MSS\n"
78458 + "Maximum TCP Segment Size\n")
78460 + return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]);
78463 DEFUN (no_ipv6_route_ifname_flags_pref,
78464 no_ipv6_route_ifname_flags_pref_cmd,
78465 "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>",
78466 @@ -1497,6 +2403,195 @@
78467 return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]);
78470 +#ifdef HAVE_MPLS
78471 +static int
78472 +static_ipv6_func_mpls (struct vty *vty, int add_cmd, const char *dest,
78473 + const char *addr, const char *distance, const char **argv)
78475 + struct zmpls_out_segment out;
78476 + int result;
78478 + memset (&out, 0, sizeof (out));
78479 + out.owner = ZEBRA_ROUTE_STATIC;
78480 + result = nhlfe_parse (vty, argv, &out, addr);
78481 + if (result != CMD_SUCCESS)
78482 + return result;
78484 + out.index = mpls_out_segment_find_index_by_nhlfe(&out);
78486 + if (add_cmd)
78488 + if (out.index)
78490 + vty_out(vty, "NHLFE already exists%s",VTY_NEWLINE);
78491 + return CMD_WARNING;
78494 + if ((result = mpls_out_segment_register (&out)))
78496 + vty_out(vty, "Unable to register NHLFE(%d)%s",result, VTY_NEWLINE);
78497 + return CMD_WARNING;
78501 + result = static_ipv6_func (vty, add_cmd, dest, NULL, NULL, NULL, distance);
78503 + if (add_cmd)
78505 + if (result != CMD_SUCCESS)
78507 + mpls_out_segment_unregister_by_index (out.index);
78508 + return CMD_WARNING;
78511 + else
78513 + mpls_out_segment_unregister_by_index (out.index);
78515 + return CMD_SUCCESS;
78518 +DEFUN (ipv6_route_mpls,
78519 + ipv6_route_mpls_cmd,
78520 + "ipv6 route X:X::X:X/M (gen|atm|fr) VALUE nexthop INTERFACE",
78521 + IP_STR
78522 + "Establish static routes\n"
78523 + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
78524 + "Out-going generic MPLS label (16 - 2^20-1)\n"
78525 + "Out-going ATM MPLS label (VPI/VCI)\n"
78526 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
78527 + "Out-going label value\n"
78528 + "Nexthop\n"
78529 + "IPv6 gateway interface name\n")
78531 + return static_ipv6_func_mpls (vty, 1, argv[0], NULL, NULL, &argv[1]);
78534 +DEFUN (ipv6_route_mpls_addr,
78535 + ipv6_route_mpls_addr_cmd,
78536 + "ipv6 route X:X::X:X/M (gen|atm|fr) VALUE nexthop INTERFACE ADDR",
78537 + IP_STR
78538 + "Establish static routes\n"
78539 + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
78540 + "Out-going generic MPLS label (16 - 2^20-1)\n"
78541 + "Out-going ATM MPLS label (VPI/VCI)\n"
78542 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
78543 + "Out-going label value\n"
78544 + "Nexthop\n"
78545 + "IPv6 gateway interface name\n"
78546 + "IPv6 gateway address\n")
78548 + return static_ipv6_func_mpls (vty, 1, argv[0], argv[4], NULL, &argv[1]);
78551 +DEFUN (ipv6_route_mpls_pref,
78552 + ipv6_route_mpls_pref_cmd,
78553 + "ipv6 route X:X::X:X/M (gen|atm|fr) VALUE nexthop INTERFACE <1-255>",
78554 + IP_STR
78555 + "Establish static routes\n"
78556 + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
78557 + "Out-going generic MPLS label (16 - 2^20-1)\n"
78558 + "Out-going ATM MPLS label (VPI/VCI)\n"
78559 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
78560 + "Out-going label value\n"
78561 + "Nexthop\n"
78562 + "IPv6 gateway interface name\n"
78563 + "Distance value for this prefix\n")
78565 + return static_ipv6_func_mpls (vty, 1, argv[0], NULL, argv[4], &argv[1]);
78568 +DEFUN (ipv6_route_mpls_pref_addr,
78569 + ipv6_route_mpls_pref_addr_cmd,
78570 + "ipv6 route X:X::X:X/M (gen|atm|fr) VALUE nexthop INTERFACE ADDR <1-255>",
78571 + IP_STR
78572 + "Establish static routes\n"
78573 + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
78574 + "Out-going generic MPLS label (16 - 2^20-1)\n"
78575 + "Out-going ATM MPLS label (VPI/VCI)\n"
78576 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
78577 + "Out-going label value\n"
78578 + "Nexthop\n"
78579 + "IPv6 gateway interface name\n"
78580 + "IPv6 gateway address\n"
78581 + "Distance value for this prefix\n")
78583 + return static_ipv6_func_mpls (vty, 1, argv[0], argv[4], argv[5], &argv[1]);
78586 +DEFUN (no_ipv6_route_mpls,
78587 + no_ipv6_route_mpls_cmd,
78588 + "no ipv6 route X:X::X:X/M (gen|atm|fr) VALUE nexthop INTERFACE",
78589 + NO_STR
78590 + IP_STR
78591 + "Establish static routes\n"
78592 + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
78593 + "Out-going generic MPLS label (16 - 2^20-1)\n"
78594 + "Out-going ATM MPLS label (VPI/VCI)\n"
78595 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
78596 + "Out-going label value\n"
78597 + "Nexthop\n"
78598 + "IPv6 gateway interface name\n")
78600 + return static_ipv6_func_mpls (vty, 0, argv[0], NULL, NULL, &argv[1]);
78603 +DEFUN (no_ipv6_route_mpls_addr,
78604 + no_ipv6_route_mpls_addr_cmd,
78605 + "no ipv6 route X:X::X:X/M (gen|atm|fr) VALUE nexthop INTERFACE ADDR",
78606 + NO_STR
78607 + IP_STR
78608 + "Establish static routes\n"
78609 + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
78610 + "Out-going generic MPLS label (16 - 2^20-1)\n"
78611 + "Out-going ATM MPLS label (VPI/VCI)\n"
78612 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
78613 + "Out-going label value\n"
78614 + "Nexthop\n"
78615 + "IPv6 gateway interface name\n"
78616 + "IPv6 gateway address\n")
78618 + return static_ipv6_func_mpls (vty, 0, argv[0], argv[4], NULL, &argv[1]);
78621 +DEFUN (no_ipv6_route_mpls_pref,
78622 + no_ipv6_route_mpls_pref_cmd,
78623 + "no ipv6 route X:X::X:X/M (gen|atm|fr) VALUE nexthop INTERFACE <1-255>",
78624 + NO_STR
78625 + IP_STR
78626 + "Establish static routes\n"
78627 + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
78628 + "Out-going generic MPLS label (16 - 2^20-1)\n"
78629 + "Out-going ATM MPLS label (VPI/VCI)\n"
78630 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
78631 + "Out-going label value\n"
78632 + "Nexthop\n"
78633 + "IPv6 gateway interface name\n"
78634 + "Distance value for this prefix\n")
78636 + return static_ipv6_func_mpls (vty, 0, argv[0], NULL, argv[4], &argv[1]);
78639 +DEFUN (no_ipv6_route_mpls_pref_addr,
78640 + no_ipv6_route_mpls_pref_addr_cmd,
78641 + "no ipv6 route X:X::X:X/M (gen|atm|fr) VALUE nexthop INTERFACE ADDR <1-255>",
78642 + NO_STR
78643 + IP_STR
78644 + "Establish static routes\n"
78645 + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
78646 + "Out-going generic MPLS label (16 - 2^20-1)\n"
78647 + "Out-going ATM MPLS label (VPI/VCI)\n"
78648 + "Out-going Frame Relay MPLS label (16 - 2^17-1)\n"
78649 + "Out-going label value\n"
78650 + "Nexthop\n"
78651 + "IPv6 gateway interface name\n"
78652 + "IPv6 gateway address\n"
78653 + "Distance value for this prefix\n")
78655 + return static_ipv6_func_mpls (vty, 0, argv[0], argv[4], argv[5], &argv[1]);
78657 +#endif /* HAVE_MPLS */
78659 /* New RIB. Detailed information for IPv6 route. */
78660 static void
78661 vty_show_ipv6_route_detail (struct vty *vty, struct route_node *rn)
78662 @@ -1554,32 +2649,63 @@
78664 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
78666 + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_IGNORE))
78667 + continue;
78669 vty_out (vty, " %c",
78670 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ');
78672 - switch (nexthop->type)
78673 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV6))
78675 - case NEXTHOP_TYPE_IPV6:
78676 - case NEXTHOP_TYPE_IPV6_IFINDEX:
78677 - case NEXTHOP_TYPE_IPV6_IFNAME:
78678 vty_out (vty, " %s",
78679 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
78680 - if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
78681 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFNAME))
78682 vty_out (vty, ", %s", nexthop->ifname);
78683 else if (nexthop->ifindex)
78684 vty_out (vty, ", via %s", ifindex2ifname (nexthop->ifindex));
78685 - break;
78686 - case NEXTHOP_TYPE_IFINDEX:
78688 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX))
78690 vty_out (vty, " directly connected, %s",
78691 ifindex2ifname (nexthop->ifindex));
78692 - break;
78693 - case NEXTHOP_TYPE_IFNAME:
78695 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFNAME))
78697 vty_out (vty, " directly connected, %s",
78698 nexthop->ifname);
78699 - break;
78700 - default:
78701 - break;
78703 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_DROP))
78705 + switch (nexthop->drop)
78707 + case ZEBRA_DROP_NULL:
78708 + vty_out (vty, " directly connected, Null0");
78709 + break;
78710 + case ZEBRA_DROP_REJECT:
78711 + vty_out (vty, ", reject");
78712 + break;
78713 + case ZEBRA_DROP_BLACKHOLE:
78714 + vty_out (vty, ", blackhole");
78715 + break;
78716 + default:
78717 + assert(0);
78720 +#ifdef HAVE_MPLS
78721 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_MPLS))
78723 + struct zmpls_out_segment *out;
78724 + char buf[16];
78726 + out = mpls_out_segment_find(nexthop->mpls);
78727 + if (out)
78728 + mpls_print_label(&out->nh.mpls, buf);
78729 + else
78730 + strcpy(buf, "not found");
78731 + vty_out (vty, " (label %s)", buf);
78733 +#endif
78735 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
78736 vty_out (vty, " inactive");
78738 @@ -1587,26 +2713,38 @@
78740 vty_out (vty, " (recursive");
78742 - switch (nexthop->rtype)
78743 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV6))
78745 - case NEXTHOP_TYPE_IPV6:
78746 - case NEXTHOP_TYPE_IPV6_IFINDEX:
78747 - case NEXTHOP_TYPE_IPV6_IFNAME:
78748 - vty_out (vty, " via %s)",
78749 + vty_out (vty, " via %s",
78750 inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
78751 buf, BUFSIZ));
78752 if (nexthop->rifindex)
78753 vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
78754 - break;
78755 - case NEXTHOP_TYPE_IFINDEX:
78756 - case NEXTHOP_TYPE_IFNAME:
78757 + vty_out (vty, ")");
78759 + else if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV6))
78761 vty_out (vty, " is directly connected, %s)",
78762 ifindex2ifname (nexthop->rifindex));
78763 - break;
78764 - default:
78765 - break;
78767 +#ifdef HAVE_MPLS
78768 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_MPLS))
78770 + struct zmpls_out_segment *out;
78771 + char buf[16];
78773 + out = mpls_out_segment_find(nexthop->rmpls);
78774 + if (out)
78775 + mpls_print_label(&out->nh.mpls, buf);
78776 + else
78777 + strcpy(buf, "not found");
78778 + vty_out (vty, " (label %s)", buf);
78780 +#endif
78782 + if (nexthop->advmss)
78783 + vty_out (vty, " advmss %d", nexthop->advmss);
78785 vty_out (vty, "%s", VTY_NEWLINE);
78787 vty_out (vty, "%s", VTY_NEWLINE);
78788 @@ -1624,8 +2762,12 @@
78789 /* Nexthop information. */
78790 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
78792 + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_IGNORE))
78793 + continue;
78795 if (nexthop == rib->nexthop)
78798 /* Prefix information. */
78799 len = vty_out (vty, "%c%c%c %s/%d",
78800 zebra_route_char (rib->type),
78801 @@ -1648,29 +2790,40 @@
78802 ? '*' : ' ',
78803 len - 3, ' ');
78805 - switch (nexthop->type)
78806 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV6))
78808 - case NEXTHOP_TYPE_IPV6:
78809 - case NEXTHOP_TYPE_IPV6_IFINDEX:
78810 - case NEXTHOP_TYPE_IPV6_IFNAME:
78811 vty_out (vty, " via %s",
78812 inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
78813 - if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
78814 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFNAME))
78815 vty_out (vty, ", %s", nexthop->ifname);
78816 else if (nexthop->ifindex)
78817 vty_out (vty, ", %s", ifindex2ifname (nexthop->ifindex));
78818 - break;
78819 - case NEXTHOP_TYPE_IFINDEX:
78821 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX))
78823 vty_out (vty, " is directly connected, %s",
78824 ifindex2ifname (nexthop->ifindex));
78825 - break;
78826 - case NEXTHOP_TYPE_IFNAME:
78828 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFNAME))
78830 vty_out (vty, " is directly connected, %s",
78831 nexthop->ifname);
78832 - break;
78833 - default:
78834 - break;
78836 +#ifdef HAVE_MPLS
78837 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_MPLS))
78839 + struct zmpls_out_segment *out;
78840 + char buf[16];
78842 + out = mpls_out_segment_find(nexthop->mpls);
78843 + if (out)
78844 + mpls_print_label(&out->nh.mpls, buf);
78845 + else
78846 + strcpy(buf, "not found");
78847 + vty_out (vty, " (label %s)", buf);
78849 +#endif
78851 if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
78852 vty_out (vty, " inactive");
78854 @@ -1678,32 +2831,57 @@
78856 vty_out (vty, " (recursive");
78858 - switch (nexthop->rtype)
78859 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IPV6))
78861 - case NEXTHOP_TYPE_IPV6:
78862 - case NEXTHOP_TYPE_IPV6_IFINDEX:
78863 - case NEXTHOP_TYPE_IPV6_IFNAME:
78864 - vty_out (vty, " via %s)",
78865 + vty_out (vty, " via %s",
78866 inet_ntop (AF_INET6, &nexthop->rgate.ipv6,
78867 buf, BUFSIZ));
78868 if (nexthop->rifindex)
78869 vty_out (vty, ", %s", ifindex2ifname (nexthop->rifindex));
78870 - break;
78871 - case NEXTHOP_TYPE_IFINDEX:
78872 - case NEXTHOP_TYPE_IFNAME:
78873 + vty_out (vty, ")");
78875 + else if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_IFINDEX))
78877 vty_out (vty, " is directly connected, %s)",
78878 ifindex2ifname (nexthop->rifindex));
78879 - break;
78880 - default:
78881 - break;
78883 + else if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_DROP))
78885 + switch (nexthop->drop)
78887 + case ZEBRA_DROP_NULL:
78888 + vty_out (vty, " directly connected, Null0");
78889 + break;
78890 + case ZEBRA_DROP_REJECT:
78891 + vty_out (vty, ", reject");
78892 + break;
78893 + case ZEBRA_DROP_BLACKHOLE:
78894 + vty_out (vty, ", blackhole");
78895 + break;
78896 + default:
78897 + assert(0);
78900 +#ifdef HAVE_MPLS
78901 + if (CHECK_FLAG (nexthop->rtype, ZEBRA_NEXTHOP_MPLS))
78903 + struct zmpls_out_segment *out;
78904 + char buf[16];
78906 + out = mpls_out_segment_find(nexthop->rmpls);
78907 + if (out)
78908 + mpls_print_label(&out->nh.mpls, buf);
78909 + else
78910 + strcpy(buf, "not found");
78911 + vty_out (vty, " (label %s)", buf);
78913 +#endif
78916 - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
78917 - vty_out (vty, ", bh");
78918 - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
78919 - vty_out (vty, ", rej");
78922 + if (nexthop->advmss)
78923 + vty_out (vty, " advmss %d", nexthop->advmss);
78925 if (rib->type == ZEBRA_ROUTE_RIPNG
78926 || rib->type == ZEBRA_ROUTE_OSPF6
78927 || rib->type == ZEBRA_ROUTE_ISIS
78928 @@ -1730,6 +2908,7 @@
78929 tm->tm_yday/7,
78930 tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
78933 vty_out (vty, "%s", VTY_NEWLINE);
78936 @@ -1842,6 +3021,8 @@
78937 type = ZEBRA_ROUTE_RIPNG;
78938 else if (strncmp (argv[0], "s", 1) == 0)
78939 type = ZEBRA_ROUTE_STATIC;
78940 + else if (strncmp (argv[0], "l", 1) == 0)
78941 + type = ZEBRA_ROUTE_LDP;
78942 else
78944 vty_out (vty, "Unknown route type%s", VTY_NEWLINE);
78945 @@ -1948,7 +3129,7 @@
78946 static_config_ipv6 (struct vty *vty)
78948 struct route_node *rn;
78949 - struct static_ipv6 *si;
78950 + struct static_route *si;
78951 int write;
78952 char buf[BUFSIZ];
78953 struct route_table *stable;
78954 @@ -1967,28 +3148,39 @@
78955 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),
78956 rn->p.prefixlen);
78958 - switch (si->type)
78959 + if (CHECK_FLAG(si->nh.type, ZEBRA_NEXTHOP_DROP))
78960 + switch(si->nh.gw.drop)
78962 + case ZEBRA_DROP_NULL:
78963 + vty_out (vty, " Null0");
78964 + break;
78965 + case ZEBRA_DROP_REJECT:
78966 + vty_out (vty, " %s", "reject");
78967 + break;
78968 + case ZEBRA_DROP_BLACKHOLE:
78969 + vty_out (vty, " %s", "blackhole");
78970 + break;
78971 + default:
78972 + assert(0);
78974 + else
78976 - case STATIC_IPV6_GATEWAY:
78977 - vty_out (vty, " %s", inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ));
78978 - break;
78979 - case STATIC_IPV6_IFNAME:
78980 - vty_out (vty, " %s", si->ifname);
78981 - break;
78982 - case STATIC_IPV6_GATEWAY_IFNAME:
78983 - vty_out (vty, " %s %s",
78984 - inet_ntop (AF_INET6, &si->ipv6, buf, BUFSIZ), si->ifname);
78985 - break;
78986 + if (CHECK_FLAG(si->nh.type, ZEBRA_NEXTHOP_IPV6))
78987 + vty_out (vty, " %s", inet_ntop (AF_INET6, &si->nh.gw.ipv6,buf,BUFSIZ));
78988 + if (CHECK_FLAG(si->nh.type, ZEBRA_NEXTHOP_IFNAME))
78989 + vty_out (vty, " %s", si->nh.intf.name);
78990 +#ifdef HAVE_MPLS
78991 + if (CHECK_FLAG(si->nh.type, ZEBRA_NEXTHOP_MPLS))
78992 + vty_out (vty, " 0x%08x", si->nh.mpls);
78993 +#endif
78996 - if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
78997 - vty_out (vty, " %s", "reject");
78999 - if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE))
79000 - vty_out (vty, " %s", "blackhole");
79002 if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
79003 vty_out (vty, " %d", si->distance);
79005 + if (si->nh.advmss)
79006 + vty_out (vty, " advmss %d", si->nh.advmss);
79008 vty_out (vty, "%s", VTY_NEWLINE);
79010 write = 1;
79011 @@ -2070,6 +3262,37 @@
79012 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_cmd);
79013 install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance2_cmd);
79015 + install_element (CONFIG_NODE, &ip_route_advmss_cmd);
79016 + install_element (CONFIG_NODE, &ip_route_mask_advmss_cmd);
79017 + install_element (CONFIG_NODE, &ip_route_distance_advmss_cmd);
79018 + install_element (CONFIG_NODE, &ip_route_mask_distance_advmss_cmd);
79019 + install_element (CONFIG_NODE, &no_ip_route_advmss_cmd);
79020 + install_element (CONFIG_NODE, &no_ip_route_mask_advmss_cmd);
79021 + install_element (CONFIG_NODE, &no_ip_route_distance_advmss_cmd);
79022 + install_element (CONFIG_NODE, &no_ip_route_mask_distance_advmss_cmd);
79023 +#ifdef HAVE_MPLS
79024 + install_element (CONFIG_NODE, &ip_route_mpls_cmd);
79025 + install_element (CONFIG_NODE, &ip_route_mpls_addr_cmd);
79026 + install_element (CONFIG_NODE, &ip_route_mpls_mask_cmd);
79027 + install_element (CONFIG_NODE, &ip_route_mpls_mask_addr_cmd);
79028 + install_element (CONFIG_NODE, &ip_route_mpls_distance_cmd);
79029 + install_element (CONFIG_NODE, &ip_route_mpls_distance_addr_cmd);
79030 + install_element (CONFIG_NODE, &ip_route_mpls_mask_distance_cmd);
79031 + install_element (CONFIG_NODE, &ip_route_mpls_mask_distance_addr_cmd);
79032 + install_element (CONFIG_NODE, &no_ip_route_mpls_cmd);
79033 + install_element (CONFIG_NODE, &no_ip_route_mpls_addr_cmd);
79034 + install_element (CONFIG_NODE, &no_ip_route_mpls_mask_cmd);
79035 + install_element (CONFIG_NODE, &no_ip_route_mpls_mask_addr_cmd);
79036 + install_element (CONFIG_NODE, &no_ip_route_mpls_distance_cmd);
79037 + install_element (CONFIG_NODE, &no_ip_route_mpls_distance_addr_cmd);
79038 + install_element (CONFIG_NODE, &no_ip_route_mpls_mask_distance_cmd);
79039 + install_element (CONFIG_NODE, &no_ip_route_mpls_mask_distance_addr_cmd);
79041 + install_element (CONFIG_NODE, &ip_route_mpls_advmss_cmd);
79042 + install_element (CONFIG_NODE, &ip_route_mpls_addr_advmss_cmd);
79043 + install_element (CONFIG_NODE, &no_ip_route_mpls_advmss_cmd);
79044 + install_element (CONFIG_NODE, &no_ip_route_mpls_addr_advmss_cmd);
79045 +#endif /* HAVE_MPLS */
79046 install_element (VIEW_NODE, &show_ip_route_cmd);
79047 install_element (VIEW_NODE, &show_ip_route_addr_cmd);
79048 install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
79049 @@ -2105,11 +3328,29 @@
79050 install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_cmd);
79051 install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_cmd);
79052 install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_cmd);
79053 + install_element (CONFIG_NODE, &ipv6_route_advmss_cmd);
79054 + install_element (CONFIG_NODE, &ipv6_route_ifname_advmss_cmd);
79055 + install_element (CONFIG_NODE, &ipv6_route_pref_advmss_cmd);
79056 + install_element (CONFIG_NODE, &ipv6_route_ifname_pref_advmss_cmd);
79057 + install_element (CONFIG_NODE, &no_ipv6_route_advmss_cmd);
79058 + install_element (CONFIG_NODE, &no_ipv6_route_ifname_advmss_cmd);
79059 + install_element (CONFIG_NODE, &no_ipv6_route_pref_advmss_cmd);
79060 + install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_advmss_cmd);
79061 install_element (VIEW_NODE, &show_ipv6_route_cmd);
79062 install_element (VIEW_NODE, &show_ipv6_route_protocol_cmd);
79063 install_element (VIEW_NODE, &show_ipv6_route_addr_cmd);
79064 install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd);
79065 install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd);
79066 +#ifdef HAVE_MPLS
79067 + install_element (CONFIG_NODE, &ipv6_route_mpls_cmd);
79068 + install_element (CONFIG_NODE, &ipv6_route_mpls_addr_cmd);
79069 + install_element (CONFIG_NODE, &ipv6_route_mpls_pref_cmd);
79070 + install_element (CONFIG_NODE, &ipv6_route_mpls_pref_addr_cmd);
79071 + install_element (CONFIG_NODE, &no_ipv6_route_mpls_cmd);
79072 + install_element (CONFIG_NODE, &no_ipv6_route_mpls_addr_cmd);
79073 + install_element (CONFIG_NODE, &no_ipv6_route_mpls_pref_cmd);
79074 + install_element (CONFIG_NODE, &no_ipv6_route_mpls_pref_addr_cmd);
79075 +#endif /* HAVE_MPLS */
79076 install_element (ENABLE_NODE, &show_ipv6_route_cmd);
79077 install_element (ENABLE_NODE, &show_ipv6_route_protocol_cmd);
79078 install_element (ENABLE_NODE, &show_ipv6_route_addr_cmd);
79079 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/zserv.c quagga-mpls/zebra/zserv.c
79080 --- quagga/zebra/zserv.c 2007-05-09 15:59:35.000000000 -0500
79081 +++ quagga-mpls/zebra/zserv.c 2008-02-19 23:19:40.000000000 -0600
79082 @@ -336,6 +336,25 @@
79083 return zebra_server_send_message(client);
79086 +static void
79087 +zsend_nexthop (struct zapi_nexthop *nh, struct nexthop *nexthop)
79089 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_DROP))
79090 + nh->gw.drop = nexthop->drop;
79091 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV4))
79092 + nh->gw.ipv4 = nexthop->gate.ipv4;
79093 +#ifdef HAVE_IPV6
79094 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IPV6))
79095 + memcpy (&nh->gw.ipv6, &nexthop->gate.ipv6, 16);
79096 +#endif
79097 + if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFINDEX))
79098 + nh->intf.index = nexthop->ifindex;
79099 + else if (CHECK_FLAG (nexthop->type, ZEBRA_NEXTHOP_IFNAME))
79100 + strncpy (nh->intf.name, nexthop->ifname, IFNAMSIZ);
79102 + nh->type = nexthop->type;
79106 * The zebra server sends the clients a ZEBRA_IPV4_ROUTE_ADD or a
79107 * ZEBRA_IPV6_ROUTE_ADD via zsend_route_multipath in the following
79108 @@ -363,113 +382,103 @@
79109 zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
79110 struct rib *rib)
79112 - int psize;
79113 struct stream *s;
79114 + int nhnum;
79115 struct nexthop *nexthop;
79116 - unsigned long nhnummark = 0, messmark = 0;
79117 - int nhnum = 0;
79118 u_char zapi_flags = 0;
79120 s = client->obuf;
79121 - stream_reset (s);
79123 - zserv_create_header (s, cmd);
79125 - /* Put type and nexthop. */
79126 - stream_putc (s, rib->type);
79127 - stream_putc (s, rib->flags);
79129 - /* marker for message flags field */
79130 - messmark = stream_get_endp (s);
79131 - stream_putc (s, 0);
79133 - /* Prefix. */
79134 - psize = PSIZE (p->prefixlen);
79135 - stream_putc (s, p->prefixlen);
79136 - stream_write (s, (u_char *) & p->u.prefix, psize);
79138 - /*
79139 - * XXX The message format sent by zebra below does not match the format
79140 - * of the corresponding message expected by the zebra server
79141 - * itself (e.g., see zread_ipv4_add). The nexthop_num is not set correctly,
79142 - * (is there a bug on the client side if more than one segment is sent?)
79143 - * nexthop ZEBRA_NEXTHOP_IPV4 is never set, ZEBRA_NEXTHOP_IFINDEX
79144 - * is hard-coded.
79145 - */
79146 - /* Nexthop */
79148 - for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
79149 + if (p->family == AF_INET)
79151 - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
79152 + struct zapi_ipv4 api;
79154 + memset (&api, 0, sizeof(api));
79155 + api.type = rib->type;
79156 + api.flags = rib->flags;
79157 + nhnum = 0;
79159 + /* Nexthop */
79160 + for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
79162 - SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
79163 - SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
79165 - if (nhnummark == 0)
79166 + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
79168 - nhnummark = stream_get_endp (s);
79169 - stream_putc (s, 1); /* placeholder */
79170 + SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
79171 + zsend_nexthop(&api.nexthop[nhnum], nexthop);
79172 + nhnum++;
79175 - nhnum++;
79177 + api.nexthop_num = nhnum;
79179 - switch(nexthop->type)
79181 - case NEXTHOP_TYPE_IPV4:
79182 - case NEXTHOP_TYPE_IPV4_IFINDEX:
79183 - stream_put_in_addr (s, &nexthop->gate.ipv4);
79184 - break;
79185 -#ifdef HAVE_IPV6
79186 - case NEXTHOP_TYPE_IPV6:
79187 - case NEXTHOP_TYPE_IPV6_IFINDEX:
79188 - case NEXTHOP_TYPE_IPV6_IFNAME:
79189 - stream_write (s, (u_char *) &nexthop->gate.ipv6, 16);
79190 - break;
79191 -#endif
79192 - default:
79193 - if (cmd == ZEBRA_IPV4_ROUTE_ADD
79194 - || cmd == ZEBRA_IPV4_ROUTE_DELETE)
79196 - struct in_addr empty;
79197 - memset (&empty, 0, sizeof (struct in_addr));
79198 - stream_write (s, (u_char *) &empty, IPV4_MAX_BYTELEN);
79200 - else
79202 - struct in6_addr empty;
79203 - memset (&empty, 0, sizeof (struct in6_addr));
79204 - stream_write (s, (u_char *) &empty, IPV6_MAX_BYTELEN);
79208 - /* Interface index. */
79209 - stream_putc (s, 1);
79210 - stream_putl (s, nexthop->ifindex);
79211 + /* Distance */
79212 + if (CHECK_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE))
79213 + api.distance = rib->distance;
79215 - break;
79216 + /* Metric */
79217 + if (cmd == ZEBRA_IPV4_ROUTE_ADD)
79219 + SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
79220 + api.distance = rib->distance;
79221 + SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
79222 + api.metric = rib->metric;
79226 + /* write real message flags value */
79227 + api.message = zapi_flags;
79229 - /* Metric */
79230 - if (cmd == ZEBRA_IPV4_ROUTE_ADD || ZEBRA_IPV6_ROUTE_ADD)
79232 - SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
79233 - stream_putc (s, rib->distance);
79234 - SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
79235 - stream_putl (s, rib->metric);
79236 + zapi_ipv4_write (cmd, s, (struct prefix_ipv4*)p, &api);
79238 + /* Write packet length. */
79239 + stream_putw_at (s, 0, stream_get_endp (s));
79241 + return zebra_server_send_message (client);
79243 +#ifdef HAVE_IPV6
79244 + else if (p->family == AF_INET6)
79246 + struct zapi_ipv6 api;
79248 - /* write real message flags value */
79249 - stream_putc_at (s, messmark, zapi_flags);
79251 - /* Write next-hop number */
79252 - if (nhnummark)
79253 - stream_putc_at (s, nhnummark, nhnum);
79254 + memset (&api, 0, sizeof(api));
79255 + api.type = rib->type;
79256 + api.flags = rib->flags;
79257 + nhnum = 0;
79259 + /* Nexthop */
79260 + for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
79262 + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
79264 + SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
79265 + zsend_nexthop(&api.nexthop[nhnum], nexthop);
79266 + nhnum++;
79269 + api.nexthop_num = nhnum;
79271 + /* Distance */
79272 + if (CHECK_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE))
79273 + api.distance = rib->distance;
79275 + /* Metric */
79276 + if (cmd == ZEBRA_IPV6_ROUTE_ADD)
79278 + SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
79279 + api.distance = rib->distance;
79280 + SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
79281 + api.metric = rib->metric;
79284 - /* Write packet size. */
79285 - stream_putw_at (s, 0, stream_get_endp (s));
79286 + /* write real message flags value */
79287 + api.message = zapi_flags;
79289 - return zebra_server_send_message(client);
79290 + zapi_ipv6_write (cmd, s, (struct prefix_ipv6*)p, &api);
79292 + /* Write packet length. */
79293 + stream_putw_at (s, 0, stream_get_endp (s));
79295 + return zebra_server_send_message (client);
79297 +#endif
79298 + return 0;
79301 #ifdef HAVE_IPV6
79302 @@ -481,9 +490,16 @@
79303 unsigned long nump;
79304 u_char num;
79305 struct nexthop *nexthop;
79306 + struct zapi_nexthop znh;
79307 + struct prefix p;
79309 + memset(&p, 0, sizeof(struct prefix));
79310 + p.family = AF_INET6;
79311 + p.prefixlen = IPV6_MAX_PREFIXLEN;
79312 + IPV6_ADDR_COPY (&p.u.prefix6, addr);
79314 /* Lookup nexthop. */
79315 - rib = rib_match_ipv6 (addr);
79316 + rib = rib_match_route (&p);
79318 /* Get output stream. */
79319 s = client->obuf;
79320 @@ -502,25 +518,8 @@
79321 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
79322 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
79324 - stream_putc (s, nexthop->type);
79325 - switch (nexthop->type)
79327 - case ZEBRA_NEXTHOP_IPV6:
79328 - stream_put (s, &nexthop->gate.ipv6, 16);
79329 - break;
79330 - case ZEBRA_NEXTHOP_IPV6_IFINDEX:
79331 - case ZEBRA_NEXTHOP_IPV6_IFNAME:
79332 - stream_put (s, &nexthop->gate.ipv6, 16);
79333 - stream_putl (s, nexthop->ifindex);
79334 - break;
79335 - case ZEBRA_NEXTHOP_IFINDEX:
79336 - case ZEBRA_NEXTHOP_IFNAME:
79337 - stream_putl (s, nexthop->ifindex);
79338 - break;
79339 - default:
79340 - /* do nothing */
79341 - break;
79343 + zsend_nexthop(&znh, nexthop);
79344 + zapi_nexthop_write(s, &znh);
79345 num++;
79347 stream_putc_at (s, nump, num);
79348 @@ -545,9 +544,16 @@
79349 unsigned long nump;
79350 u_char num;
79351 struct nexthop *nexthop;
79352 + struct zapi_nexthop znh;
79353 + struct prefix p;
79355 + memset(&p, 0, sizeof(struct prefix));
79356 + p.family = AF_INET;
79357 + p.prefixlen = IPV4_MAX_PREFIXLEN;
79358 + IPV4_ADDR_COPY (&p.u.prefix4, &addr);
79360 /* Lookup nexthop. */
79361 - rib = rib_match_ipv4 (addr);
79362 + rib = rib_match_route (&p);
79364 /* Get output stream. */
79365 s = client->obuf;
79366 @@ -566,20 +572,8 @@
79367 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
79368 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
79370 - stream_putc (s, nexthop->type);
79371 - switch (nexthop->type)
79373 - case ZEBRA_NEXTHOP_IPV4:
79374 - stream_put_in_addr (s, &nexthop->gate.ipv4);
79375 - break;
79376 - case ZEBRA_NEXTHOP_IFINDEX:
79377 - case ZEBRA_NEXTHOP_IFNAME:
79378 - stream_putl (s, nexthop->ifindex);
79379 - break;
79380 - default:
79381 - /* do nothing */
79382 - break;
79384 + zsend_nexthop(&znh, nexthop);
79385 + zapi_nexthop_write(s, &znh);
79386 num++;
79388 stream_putc_at (s, nump, num);
79389 @@ -603,9 +597,10 @@
79390 unsigned long nump;
79391 u_char num;
79392 struct nexthop *nexthop;
79393 + struct zapi_nexthop znh;
79395 /* Lookup nexthop. */
79396 - rib = rib_lookup_ipv4 (p);
79397 + rib = rib_lookup_route ((struct prefix*)p);
79399 /* Get output stream. */
79400 s = client->obuf;
79401 @@ -624,20 +619,8 @@
79402 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
79403 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
79405 - stream_putc (s, nexthop->type);
79406 - switch (nexthop->type)
79408 - case ZEBRA_NEXTHOP_IPV4:
79409 - stream_put_in_addr (s, &nexthop->gate.ipv4);
79410 - break;
79411 - case ZEBRA_NEXTHOP_IFINDEX:
79412 - case ZEBRA_NEXTHOP_IFNAME:
79413 - stream_putl (s, nexthop->ifindex);
79414 - break;
79415 - default:
79416 - /* do nothing */
79417 - break;
79419 + zsend_nexthop(&znh, nexthop);
79420 + zapi_nexthop_write(s, &znh);
79421 num++;
79423 stream_putc_at (s, nump, num);
79424 @@ -734,76 +717,41 @@
79425 int i;
79426 struct rib *rib;
79427 struct prefix_ipv4 p;
79428 - u_char message;
79429 - struct in_addr nexthop;
79430 - u_char nexthop_num;
79431 - u_char nexthop_type;
79432 struct stream *s;
79433 - unsigned int ifindex;
79434 - u_char ifname_len;
79435 + struct zapi_ipv4 api;
79437 /* Get input stream. */
79438 s = client->ibuf;
79439 + memset (&api, 0, sizeof (api));
79440 + memset (&p, 0, sizeof (p));
79441 + zapi_ipv4_read (s, length, &api, &p);
79443 /* Allocate new rib. */
79444 rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
79446 /* Type, flags, message. */
79447 - rib->type = stream_getc (s);
79448 - rib->flags = stream_getc (s);
79449 - message = stream_getc (s);
79450 + rib->type = api.type;
79451 + rib->flags = api.flags;
79452 rib->uptime = time (NULL);
79454 - /* IPv4 prefix. */
79455 - memset (&p, 0, sizeof (struct prefix_ipv4));
79456 - p.family = AF_INET;
79457 - p.prefixlen = stream_getc (s);
79458 - stream_get (&p.prefix, s, PSIZE (p.prefixlen));
79460 /* Nexthop parse. */
79461 - if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
79462 + if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
79464 - nexthop_num = stream_getc (s);
79466 - for (i = 0; i < nexthop_num; i++)
79468 - nexthop_type = stream_getc (s);
79470 - switch (nexthop_type)
79472 - case ZEBRA_NEXTHOP_IFINDEX:
79473 - ifindex = stream_getl (s);
79474 - nexthop_ifindex_add (rib, ifindex);
79475 - break;
79476 - case ZEBRA_NEXTHOP_IFNAME:
79477 - ifname_len = stream_getc (s);
79478 - stream_forward_getp (s, ifname_len);
79479 - break;
79480 - case ZEBRA_NEXTHOP_IPV4:
79481 - nexthop.s_addr = stream_get_ipv4 (s);
79482 - nexthop_ipv4_add (rib, &nexthop, NULL);
79483 - break;
79484 - case ZEBRA_NEXTHOP_IPV6:
79485 - stream_forward_getp (s, IPV6_MAX_BYTELEN);
79486 - break;
79487 - case ZEBRA_NEXTHOP_BLACKHOLE:
79488 - nexthop_blackhole_add (rib);
79489 - break;
79492 + for (i = 0; i < api.nexthop_num; i++)
79493 + nexthop_zapi_nexthop_add(rib, &api.nexthop[i]);
79496 /* Distance. */
79497 - if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
79498 - rib->distance = stream_getc (s);
79499 + if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
79500 + rib->distance = api.distance;
79502 /* Metric. */
79503 - if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
79504 - rib->metric = stream_getl (s);
79505 + if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
79506 + rib->metric = api.metric;
79508 /* Table */
79509 rib->table=zebrad.rtm_table_default;
79510 - rib_add_ipv4_multipath (&p, rib);
79511 + rib_add_multipath ((struct prefix*)&p, rib);
79512 return 0;
79515 @@ -812,72 +760,22 @@
79516 zread_ipv4_delete (struct zserv *client, u_short length)
79518 int i;
79519 + struct prefix_ipv4 p;
79520 struct stream *s;
79521 struct zapi_ipv4 api;
79522 - struct in_addr nexthop;
79523 - unsigned long ifindex;
79524 - struct prefix_ipv4 p;
79525 - u_char nexthop_num;
79526 - u_char nexthop_type;
79527 - u_char ifname_len;
79529 - s = client->ibuf;
79530 - ifindex = 0;
79531 - nexthop.s_addr = 0;
79533 - /* Type, flags, message. */
79534 - api.type = stream_getc (s);
79535 - api.flags = stream_getc (s);
79536 - api.message = stream_getc (s);
79538 - /* IPv4 prefix. */
79539 - memset (&p, 0, sizeof (struct prefix_ipv4));
79540 - p.family = AF_INET;
79541 - p.prefixlen = stream_getc (s);
79542 - stream_get (&p.prefix, s, PSIZE (p.prefixlen));
79543 + /* Get input stream. */
79544 + s = client->ibuf;
79545 + memset (&api, 0, sizeof (api));
79546 + memset (&p, 0, sizeof (p));
79547 + zapi_ipv4_read (s, length, &api, &p);
79549 /* Nexthop, ifindex, distance, metric. */
79550 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
79552 - nexthop_num = stream_getc (s);
79554 - for (i = 0; i < nexthop_num; i++)
79556 - nexthop_type = stream_getc (s);
79558 - switch (nexthop_type)
79560 - case ZEBRA_NEXTHOP_IFINDEX:
79561 - ifindex = stream_getl (s);
79562 - break;
79563 - case ZEBRA_NEXTHOP_IFNAME:
79564 - ifname_len = stream_getc (s);
79565 - stream_forward_getp (s, ifname_len);
79566 - break;
79567 - case ZEBRA_NEXTHOP_IPV4:
79568 - nexthop.s_addr = stream_get_ipv4 (s);
79569 - break;
79570 - case ZEBRA_NEXTHOP_IPV6:
79571 - stream_forward_getp (s, IPV6_MAX_BYTELEN);
79572 - break;
79577 - /* Distance. */
79578 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
79579 - api.distance = stream_getc (s);
79580 - else
79581 - api.distance = 0;
79582 + for (i = 0; i < api.nexthop_num; i++)
79583 + rib_delete_route (api.type, api.flags, (struct prefix*)&p,
79584 + &api.nexthop[i], client->rtm_table);
79586 - /* Metric. */
79587 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
79588 - api.metric = stream_getl (s);
79589 - else
79590 - api.metric = 0;
79592 - rib_delete_ipv4 (api.type, api.flags, &p, &nexthop, ifindex,
79593 - client->rtm_table);
79594 return 0;
79597 @@ -910,65 +808,24 @@
79598 zread_ipv6_add (struct zserv *client, u_short length)
79600 int i;
79601 + struct prefix_ipv6 p;
79602 struct stream *s;
79603 struct zapi_ipv6 api;
79604 - struct in6_addr nexthop;
79605 - unsigned long ifindex;
79606 - struct prefix_ipv6 p;
79608 - s = client->ibuf;
79609 - ifindex = 0;
79610 - memset (&nexthop, 0, sizeof (struct in6_addr));
79612 - /* Type, flags, message. */
79613 - api.type = stream_getc (s);
79614 - api.flags = stream_getc (s);
79615 - api.message = stream_getc (s);
79617 - /* IPv4 prefix. */
79618 - memset (&p, 0, sizeof (struct prefix_ipv6));
79619 - p.family = AF_INET6;
79620 - p.prefixlen = stream_getc (s);
79621 - stream_get (&p.prefix, s, PSIZE (p.prefixlen));
79622 + /* Get input stream. */
79623 + s = client->ibuf;
79624 + memset (&api, 0, sizeof (api));
79625 + memset (&p, 0, sizeof (p));
79626 + zapi_ipv6_read (s, length, &api, &p);
79628 /* Nexthop, ifindex, distance, metric. */
79629 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
79631 - u_char nexthop_type;
79633 - api.nexthop_num = stream_getc (s);
79634 for (i = 0; i < api.nexthop_num; i++)
79636 - nexthop_type = stream_getc (s);
79638 - switch (nexthop_type)
79640 - case ZEBRA_NEXTHOP_IPV6:
79641 - stream_get (&nexthop, s, 16);
79642 - break;
79643 - case ZEBRA_NEXTHOP_IFINDEX:
79644 - ifindex = stream_getl (s);
79645 - break;
79648 + rib_add_route (api.type, api.flags, (struct prefix*)&p,
79649 + &api.nexthop[i], 0, api.metric, api.distance);
79652 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
79653 - api.distance = stream_getc (s);
79654 - else
79655 - api.distance = 0;
79657 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
79658 - api.metric = stream_getl (s);
79659 - else
79660 - api.metric = 0;
79662 - if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
79663 - rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0, api.metric,
79664 - api.distance);
79665 - else
79666 - rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0, api.metric,
79667 - api.distance);
79668 return 0;
79671 @@ -977,62 +834,24 @@
79672 zread_ipv6_delete (struct zserv *client, u_short length)
79674 int i;
79675 + struct prefix_ipv6 p;
79676 struct stream *s;
79677 struct zapi_ipv6 api;
79678 - struct in6_addr nexthop;
79679 - unsigned long ifindex;
79680 - struct prefix_ipv6 p;
79682 - s = client->ibuf;
79683 - ifindex = 0;
79684 - memset (&nexthop, 0, sizeof (struct in6_addr));
79686 - /* Type, flags, message. */
79687 - api.type = stream_getc (s);
79688 - api.flags = stream_getc (s);
79689 - api.message = stream_getc (s);
79691 - /* IPv4 prefix. */
79692 - memset (&p, 0, sizeof (struct prefix_ipv6));
79693 - p.family = AF_INET6;
79694 - p.prefixlen = stream_getc (s);
79695 - stream_get (&p.prefix, s, PSIZE (p.prefixlen));
79696 + /* Get input stream. */
79697 + s = client->ibuf;
79698 + memset (&api, 0, sizeof (api));
79699 + memset (&p, 0, sizeof (p));
79700 + zapi_ipv6_read (s, length, &api, &p);
79702 /* Nexthop, ifindex, distance, metric. */
79703 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
79705 - u_char nexthop_type;
79707 - api.nexthop_num = stream_getc (s);
79708 for (i = 0; i < api.nexthop_num; i++)
79710 - nexthop_type = stream_getc (s);
79712 - switch (nexthop_type)
79714 - case ZEBRA_NEXTHOP_IPV6:
79715 - stream_get (&nexthop, s, 16);
79716 - break;
79717 - case ZEBRA_NEXTHOP_IFINDEX:
79718 - ifindex = stream_getl (s);
79719 - break;
79722 + rib_delete_route (api.type, api.flags, (struct prefix*)&p,
79723 + &api.nexthop[i], 0);
79726 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
79727 - api.distance = stream_getc (s);
79728 - else
79729 - api.distance = 0;
79730 - if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
79731 - api.metric = stream_getl (s);
79732 - else
79733 - api.metric = 0;
79735 - if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
79736 - rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
79737 - else
79738 - rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
79739 return 0;
79742 @@ -1049,6 +868,416 @@
79744 #endif /* HAVE_IPV6 */
79746 +#ifdef HAVE_MPLS
79747 +int
79748 +zsend_mpls_xc_add (struct zserv *client, struct zmpls_xc *p)
79750 + struct zapi_mpls_xc api;
79751 + struct stream *s;
79753 + s = client->obuf;
79754 + stream_reset (s);
79756 + api.owner = p->owner;
79757 + api.index = p->index;
79758 + api.in_labelspace = p->in_labelspace;
79759 + memcpy(&api.in_label,&p->in_label, sizeof(struct zmpls_label));
79760 + api.out_index = p->out_index;
79762 + zserv_create_header (s, ZEBRA_MPLS_XC_ADD);
79763 + mpls_xc_stream_write (s, &api);
79765 + stream_putw_at (s, 0, stream_get_endp (s));
79766 + return zebra_server_send_message(client);
79769 +int
79770 +zsend_mpls_xc_delete (struct zserv *client, struct zmpls_xc *p)
79772 + struct zapi_mpls_xc api;
79773 + struct stream *s;
79775 + s = client->obuf;
79776 + stream_reset (s);
79778 + api.owner = p->owner;
79779 + api.index = p->index;
79780 + api.in_labelspace = p->in_labelspace;
79781 + memcpy(&api.in_label,&p->in_label, sizeof(struct zmpls_label));
79782 + api.out_index = p->out_index;
79784 + zserv_create_header (s, ZEBRA_MPLS_XC_DELETE);
79785 + mpls_xc_stream_write (s, &api);
79787 + stream_putw_at (s, 0, stream_get_endp (s));
79788 + return zebra_server_send_message(client);
79791 +int
79792 +zsend_mpls_in_segment_add (struct zserv *client, struct zmpls_in_segment *in)
79794 + struct zapi_mpls_in_segment api;
79795 + struct stream *s;
79797 + s = client->obuf;
79798 + stream_reset (s);
79800 + zserv_create_header (s, ZEBRA_MPLS_IN_SEGMENT_ADD);
79802 + api.owner = in->owner;
79803 + api.labelspace = in->labelspace;
79804 + api.protocol = in->protocol;
79805 + api.pop = in->pop;
79806 + memcpy (&api.label, &in->label, sizeof (api.label));
79808 + mpls_in_segment_stream_write (s, &api);
79810 + stream_putw_at (s, 0, stream_get_endp (s));
79811 + return zebra_server_send_message(client);
79814 +int
79815 +zsend_mpls_in_segment_delete (struct zserv *client, struct zmpls_in_segment *in)
79817 + struct zapi_mpls_in_segment api;
79818 + struct stream *s;
79820 + s = client->obuf;
79821 + stream_reset (s);
79823 + zserv_create_header (s, ZEBRA_MPLS_IN_SEGMENT_DELETE);
79825 + api.owner = in->owner;
79826 + api.labelspace = in->labelspace;
79827 + api.protocol = in->protocol;
79828 + api.pop = in->pop;
79829 + memcpy (&api.label, &in->label, sizeof (api.label));
79831 + mpls_in_segment_stream_write (s, &api);
79833 + stream_putw_at (s, 0, stream_get_endp (s));
79834 + return zebra_server_send_message(client);
79837 +int
79838 +zsend_mpls_out_segment_add (struct zserv *client, struct zmpls_out_segment *out)
79840 + struct zapi_mpls_out_segment api;
79841 + struct stream *s;
79843 + api.owner = out->owner;
79845 + memcpy(&api.nh, &out->nh, sizeof(struct zapi_nexthop));
79847 + s = client->obuf;
79848 + stream_reset (s);
79850 + zserv_create_header (s, ZEBRA_MPLS_OUT_SEGMENT_ADD);
79851 + mpls_out_segment_stream_write (s, &api);
79853 + stream_putw_at (s, 0, stream_get_endp (s));
79854 + return zebra_server_send_message(client);
79857 +int
79858 +zsend_mpls_out_segment_delete (struct zserv *client, struct zmpls_out_segment *out)
79860 + struct zapi_mpls_out_segment api;
79861 + struct stream *s;
79863 + api.owner = out->owner;
79865 + memcpy(&api.nh, &out->nh, sizeof(struct zapi_nexthop));
79867 + s = client->obuf;
79868 + stream_reset (s);
79870 + zserv_create_header (s, ZEBRA_MPLS_OUT_SEGMENT_DELETE);
79871 + mpls_out_segment_stream_write (s, &api);
79873 + stream_putw_at (s, 0, stream_get_endp (s));
79874 + return zebra_server_send_message(client);
79877 +int
79878 +zsend_mpls_labelspace_add (struct zserv *client, struct interface *ifp)
79880 + struct zapi_mpls_labelspace api;
79881 + struct stream *s;
79883 + s = client->obuf;
79884 + stream_reset (s);
79886 + zserv_create_header (s, ZEBRA_MPLS_LABELSPACE_ADD);
79888 + api.owner = ZEBRA_ROUTE_KERNEL;
79889 + api.labelspace = ifp->mpls_labelspace;
79890 + strncpy(api.ifname, ifp->name, INTERFACE_NAMSIZ);
79891 + mpls_labelspace_stream_write (s, &api);
79893 + stream_putw_at (s, 0, stream_get_endp (s));
79894 + return zebra_server_send_message(client);
79897 +int
79898 +zsend_mpls_labelspace_delete (struct zserv *client, struct interface *ifp)
79900 + struct zapi_mpls_labelspace api;
79901 + struct stream *s;
79903 + s = client->obuf;
79904 + stream_reset (s);
79906 + zserv_create_header (s, ZEBRA_MPLS_LABELSPACE_DELETE);
79908 + api.owner = ZEBRA_ROUTE_KERNEL;
79909 + api.labelspace = ifp->mpls_labelspace;
79910 + strncpy(api.ifname, ifp->name, INTERFACE_NAMSIZ);
79911 + mpls_labelspace_stream_write (s, &api);
79913 + stream_putw_at (s, 0, stream_get_endp (s));
79914 + return zebra_server_send_message(client);
79917 +int
79918 +zsend_mpls_ftn_add (struct zserv *client, struct zmpls_ftn *ftn)
79920 + struct zapi_mpls_ftn api;
79921 + struct stream *s;
79923 + s = client->obuf;
79924 + stream_reset (s);
79926 + zserv_create_header (s, ZEBRA_MPLS_FTN_ADD);
79928 + api.owner = ftn->owner;
79929 + api.out_index = ftn->out_index;
79930 + memcpy(&api.fec.u.p, &ftn->fec.u.p, sizeof (struct prefix));
79931 + if (ftn->fec.u.p.family == AF_INET) {
79932 + api.fec.type = ZEBRA_MPLS_FEC_IPV4;
79933 + } else if (ftn->fec.u.p.family == AF_INET6) {
79934 + api.fec.type = ZEBRA_MPLS_FEC_IPV6;
79935 + } else {
79936 + assert (0);
79938 + mpls_ftn_stream_write (s, &api);
79940 + stream_putw_at (s, 0, stream_get_endp (s));
79941 + return zebra_server_send_message(client);
79944 +int
79945 +zsend_mpls_ftn_delete (struct zserv *client, struct zmpls_ftn *ftn)
79947 + struct zapi_mpls_ftn api;
79948 + struct stream *s;
79950 + s = client->obuf;
79951 + stream_reset (s);
79953 + zserv_create_header (s, ZEBRA_MPLS_FTN_DELETE);
79955 + api.owner = ftn->owner;
79956 + api.out_index = ftn->out_index;
79957 + memcpy(&api.fec.u.p, &ftn->fec.u.p, sizeof (struct prefix));
79958 + if (ftn->fec.u.p.family == AF_INET) {
79959 + api.fec.type = ZEBRA_MPLS_FEC_IPV4;
79960 + } else if (ftn->fec.u.p.family == AF_INET6) {
79961 + api.fec.type = ZEBRA_MPLS_FEC_IPV6;
79962 + } else {
79963 + assert (0);
79965 + mpls_ftn_stream_write (s, &api);
79967 + stream_putw_at (s, 0, stream_get_endp (s));
79968 + return zebra_server_send_message(client);
79971 +static void
79972 +zread_mpls_xc_add (struct zserv *client, u_short length)
79974 + struct zapi_mpls_xc api;
79975 + struct zmpls_out_segment *out;
79976 + struct zmpls_in_segment tmp;
79977 + struct zmpls_in_segment *in;
79978 + struct zmpls_xc xc;
79980 + memset(&api, 0, sizeof(api));
79981 + memset(&xc, 0, sizeof(xc));
79982 + mpls_xc_stream_read (client->ibuf, &api);
79984 + tmp.labelspace = api.in_labelspace;
79985 + memcpy(&tmp.label, &api.in_label, sizeof(struct zmpls_label));
79987 + out = mpls_out_segment_find (api.out_index);
79988 + in = mpls_in_segment_find (&tmp);
79990 + xc.in_labelspace = in->labelspace;
79991 + memcpy(&xc.in_label, &in->label, sizeof(struct zmpls_label));
79992 + xc.out_index = out->index;
79993 + xc.owner = api.owner;
79995 + mpls_xc_register (&xc);
79998 +static void
79999 +zread_mpls_xc_delete (struct zserv *client, u_short length)
80001 + struct zapi_mpls_xc api;
80002 + struct zmpls_in_segment tmp;
80003 + struct zmpls_in_segment *in;
80004 + struct zmpls_xc *xc;
80006 + memset(&api, 0, sizeof(api));
80007 + memset(&tmp, 0, sizeof(tmp));
80008 + mpls_xc_stream_read (client->ibuf, &api);
80010 + memcpy(&tmp.label, &api.in_label, sizeof(struct zmpls_label));
80011 + tmp.labelspace = api.in_labelspace;
80012 + in = mpls_in_segment_find (&tmp);
80013 + xc = mpls_xc_find (in->xc);
80015 + if (xc)
80016 + mpls_xc_unregister (xc);
80017 + else
80018 + zlog_warn("zread_mpls_xc_delete: xc %d does not exist", in->xc);
80021 +static void
80022 +zread_mpls_in_segment_add (struct zserv *client, u_short length)
80024 + struct zapi_mpls_in_segment api;
80025 + struct zmpls_in_segment in;
80027 + memset(&api, 0, sizeof(api));
80028 + memset(&in, 0, sizeof(in));
80029 + mpls_in_segment_stream_read (client->ibuf, &api);
80031 + in.owner = api.owner;
80032 + in.labelspace = api.labelspace;
80033 + in.protocol = api.protocol;
80034 + in.pop = api.pop;
80035 + memcpy (&in.label, &api.label, sizeof (api.label));
80037 + mpls_in_segment_register (&in, 1);
80040 +static void
80041 +zread_mpls_in_segment_delete (struct zserv *client, u_short length)
80043 + struct zapi_mpls_in_segment api;
80044 + struct zmpls_in_segment in;
80046 + memset(&api, 0, sizeof(api));
80047 + memset(&in, 0, sizeof(in));
80048 + mpls_in_segment_stream_read (client->ibuf, &api);
80049 + in.owner = api.owner;
80050 + in.labelspace = api.labelspace;
80051 + in.protocol = api.protocol;
80052 + in.pop = api.pop;
80053 + memcpy (&in.label, &api.label, sizeof (api.label));
80055 + mpls_in_segment_unregister (&in, 0);
80058 +static void
80059 +zread_mpls_out_segment_add (struct zserv *client, u_short length)
80061 + struct zapi_mpls_out_segment api;
80062 + struct zmpls_out_segment out;
80063 + struct stream *s;
80065 + memset(&api, 0, sizeof(api));
80066 + memset(&out, 0, sizeof(out));
80067 + mpls_out_segment_stream_read (client->ibuf, &api);
80069 + out.owner = api.owner;
80070 + memcpy(&out.nh, &api.nh, sizeof(struct zapi_nexthop));
80072 + mpls_out_segment_register (&out);
80073 + api.index = out.index;
80075 + /* Reset stream. */
80076 + s = client->obuf;
80077 + stream_reset (s);
80079 + zserv_create_header (s, ZEBRA_MPLS_OUT_SEGMENT_ADD);
80080 + mpls_out_segment_stream_write(s, &api);
80082 + /* Put length at the first point of the stream. */
80083 + stream_putw_at (s, 0, stream_get_endp (s));
80085 + zebra_server_send_message(client);
80088 +static void
80089 +zread_mpls_out_segment_delete (struct zserv *client, u_short length)
80091 + struct zapi_mpls_out_segment api;
80092 + struct zmpls_out_segment out;
80094 + memset(&api, 0, sizeof(api));
80095 + memset(&out, 0, sizeof(out));
80096 + mpls_out_segment_stream_read (client->ibuf, &api);
80098 + out.owner = api.owner;
80099 + memcpy(&out.nh, &api.nh, sizeof(struct zapi_nexthop));
80101 + mpls_out_segment_unregister (&out);
80104 +static void
80105 +zread_mpls_ftn_add (struct zserv *client, u_short length)
80107 + struct zapi_mpls_ftn api;
80108 + struct zmpls_ftn ftn;
80110 + memset(&api, 0, sizeof(api));
80111 + memset(&ftn, 0, sizeof(ftn));
80112 + mpls_ftn_stream_read (client->ibuf, &api);
80114 + memcpy(&ftn.fec, &api.fec, sizeof(struct zmpls_fec));
80115 + ftn.owner = api.owner;
80116 + ftn.out_index = api.out_index;
80117 + mpls_ftn_register (&ftn, 1);
80120 +static void
80121 +zread_mpls_ftn_delete (struct zserv *client, u_short length)
80123 + struct zapi_mpls_ftn api;
80124 + struct zmpls_ftn *ftn;
80126 + memset(&api, 0, sizeof(api));
80127 + mpls_ftn_stream_read (client->ibuf, &api);
80129 + ftn = mpls_ftn_find_by_fec(&api.fec);
80130 + if (ftn) {
80131 + mpls_ftn_unregister (ftn, 1);
80135 +static void
80136 +zread_mpls_labelspace_add (struct zserv *client, u_short length)
80138 + struct zapi_mpls_labelspace api;
80140 + memset(&api, 0, sizeof(api));
80141 + mpls_labelspace_stream_read (client->ibuf, &api);
80142 + assert(0);
80145 +static void
80146 +zread_mpls_labelspace_delete (struct zserv *client, u_short length)
80148 + struct zapi_mpls_labelspace api;
80150 + memset(&api, 0, sizeof(api));
80151 + mpls_labelspace_stream_read (client->ibuf, &api);
80152 + assert(0);
80154 +#endif /* HAVE_MPLS */
80156 /* Register zebra server router-id information. Send current router-id */
80157 static int
80158 zread_router_id_add (struct zserv *client, u_short length)
80159 @@ -1283,6 +1512,38 @@
80160 case ZEBRA_IPV4_IMPORT_LOOKUP:
80161 zread_ipv4_import_lookup (client, length);
80162 break;
80163 +#ifdef HAVE_MPLS
80164 + case ZEBRA_MPLS_XC_ADD:
80165 + zread_mpls_xc_add (client, length);
80166 + break;
80167 + case ZEBRA_MPLS_XC_DELETE:
80168 + zread_mpls_xc_delete (client, length);
80169 + break;
80170 + case ZEBRA_MPLS_IN_SEGMENT_ADD:
80171 + zread_mpls_in_segment_add (client, length);
80172 + break;
80173 + case ZEBRA_MPLS_IN_SEGMENT_DELETE:
80174 + zread_mpls_in_segment_delete (client, length);
80175 + break;
80176 + case ZEBRA_MPLS_OUT_SEGMENT_ADD:
80177 + zread_mpls_out_segment_add (client, length);
80178 + break;
80179 + case ZEBRA_MPLS_OUT_SEGMENT_DELETE:
80180 + zread_mpls_out_segment_delete (client, length);
80181 + break;
80182 + case ZEBRA_MPLS_LABELSPACE_ADD:
80183 + zread_mpls_labelspace_add (client, length);
80184 + break;
80185 + case ZEBRA_MPLS_LABELSPACE_DELETE:
80186 + zread_mpls_labelspace_delete (client, length);
80187 + break;
80188 + case ZEBRA_MPLS_FTN_ADD:
80189 + zread_mpls_ftn_add (client, length);
80190 + break;
80191 + case ZEBRA_MPLS_FTN_DELETE:
80192 + zread_mpls_ftn_delete (client, length);
80193 + break;
80194 +#endif /* HAVE_MPLS */
80195 default:
80196 zlog_info ("Zebra received unknown command %d", command);
80197 break;
80198 diff -uNr --exclude=.p4config --exclude=make-rpm-jleu --exclude=update-from-kernel.sh quagga/zebra/zserv.h quagga-mpls/zebra/zserv.h
80199 --- quagga/zebra/zserv.h 2008-09-04 20:37:37.000000000 -0500
80200 +++ quagga-mpls/zebra/zserv.h 2008-09-07 20:23:37.000000000 -0500
80201 @@ -25,6 +25,9 @@
80202 #include "rib.h"
80203 #include "if.h"
80204 #include "workqueue.h"
80205 +#ifdef HAVE_MPLS
80206 +#include "mpls_lib.h"
80207 +#endif
80209 /* Default port information. */
80210 #define ZEBRA_VTY_PORT 2601
80211 @@ -95,6 +98,10 @@
80212 extern void kernel_init (void);
80213 extern void route_read (void);
80214 extern void zebra_route_map_init (void);
80215 +#ifdef HAVE_MPLS
80216 +extern void mpls_kernel_init (void);
80217 +extern void mpls_read (void);
80218 +#endif
80219 extern void zebra_snmp_init (void);
80220 extern void zebra_vty_init (void);
80222 @@ -107,6 +114,38 @@
80223 struct rib *);
80224 extern int zsend_router_id_update(struct zserv *, struct prefix *);
80226 +#ifdef HAVE_MPLS
80227 +int
80228 +zsend_mpls_xc_add (struct zserv *client, struct zmpls_xc *p);
80230 +int
80231 +zsend_mpls_xc_delete (struct zserv *client, struct zmpls_xc *p);
80233 +int
80234 +zsend_mpls_in_segment_add (struct zserv *client, struct zmpls_in_segment *p);
80236 +int
80237 +zsend_mpls_in_segment_delete (struct zserv *client, struct zmpls_in_segment *p);
80239 +int
80240 +zsend_mpls_out_segment_add (struct zserv *client, struct zmpls_out_segment *p);
80242 +int
80243 +zsend_mpls_out_segment_delete (struct zserv *client, struct zmpls_out_segment *p);
80245 +int
80246 +zsend_mpls_labelspace_add (struct zserv *client, struct interface *ifp);
80248 +int
80249 +zsend_mpls_labelspace_delete (struct zserv *client, struct interface *ifp);
80251 +int
80252 +zsend_mpls_ftn_add (struct zserv *client, struct zmpls_ftn *ftn);
80254 +int
80255 +zsend_mpls_ftn_delete (struct zserv *client, struct zmpls_ftn *ftn);
80256 +#endif
80258 extern pid_t pid;
80260 #endif /* _ZEBRA_ZEBRA_H */