diff --git a/proto/ospf/hello.c b/proto/ospf/hello.c index 8f2e497f..5146f61e 100644 --- a/proto/ospf/hello.c +++ b/proto/ospf/hello.c @@ -58,8 +58,7 @@ ospf_hello_receive(struct ospf_packet *pkt, struct ospf_iface *ifa, u32 neigh_count; - OSPF_TRACE(D_PACKETS, "HELLO packet received from %I via %s%s", faddr, - (ifa->type == OSPF_IT_VLINK ? "vlink-" : ""), ifa->iface->name); + OSPF_TRACE(D_PACKETS, "HELLO packet received from %I via %s", faddr, ifa->ifname); size = ntohs(pkt->length); @@ -134,6 +133,17 @@ ospf_hello_receive(struct ospf_packet *pkt, struct ospf_iface *ifa, return; } + /* XXXX */ +#ifdef OSPFv2 + if (n && (n->rid != ntohl(pkt->routerid))) + { + OSPF_TRACE(D_EVENTS, "Neighbor %I has changed router id from %R to %R", + n->ip, n->rid, ntohl(pkt->routerid)); + ospf_neigh_remove(n); + n = NULL; + } +#endif + if (!n) { if ((ifa->type == OSPF_IT_NBMA) || (ifa->type == OSPF_IT_PTMP)) @@ -142,8 +152,7 @@ ospf_hello_receive(struct ospf_packet *pkt, struct ospf_iface *ifa, if (!nn && ifa->strictnbma) { - log(L_WARN "Ignoring new neighbor: %I on %s", faddr, - ifa->iface->name); + log(L_WARN "Ignoring new neighbor: %I on %s", faddr, ifa->ifname); return; } @@ -151,8 +160,7 @@ ospf_hello_receive(struct ospf_packet *pkt, struct ospf_iface *ifa, (((rcv_priority == 0) && nn->eligible) || ((rcv_priority > 0) && !nn->eligible))) { - log(L_ERR "Eligibility mismatch for neighbor: %I on %s", - faddr, ifa->iface->name); + log(L_ERR "Eligibility mismatch for neighbor: %I on %s", faddr, ifa->ifname); return; } @@ -160,8 +168,7 @@ ospf_hello_receive(struct ospf_packet *pkt, struct ospf_iface *ifa, nn->found = 1; } - OSPF_TRACE(D_EVENTS, "New neighbor found: %I on %s", faddr, - ifa->iface->name); + OSPF_TRACE(D_EVENTS, "New neighbor found: %I on %s", faddr, ifa->ifname); n = ospf_neighbor_new(ifa); @@ -171,7 +178,20 @@ ospf_hello_receive(struct ospf_packet *pkt, struct ospf_iface *ifa, n->bdr = rcv_bdr; n->priority = rcv_priority; n->iface_id = rcv_iface_id; + + if (n->ifa->cf->bfd) + ospf_neigh_update_bfd(n, n->ifa->bfd); } + + /* XXXX */ +#ifdef OSPFv3 /* NOTE: this could also be relevant for OSPFv2 on PtP ifaces */ + else if (!ipa_equal(faddr, n->ip)) + { + OSPF_TRACE(D_EVENTS, "Neighbor address changed from %I to %I", n->ip, faddr); + n->ip = faddr; + } +#endif + ospf_neigh_sm(n, INM_HELLOREC); two_way = 0; @@ -256,7 +276,7 @@ ospf_hello_send(struct ospf_iface *ifa, int kind, struct ospf_neighbor *dirn) return; /* Don't send any packet on stub iface */ DBG("%s: Hello/Poll timer fired on interface %s with IP %I\n", - p->name, ifa->iface->name, ifa->addr->ip); + p->name, ifa->ifname, ifa->addr->ip); pkt = ospf_tx_buffer(ifa); ospf_pkt_fill_hdr(ifa, pkt, HELLO_P); @@ -300,7 +320,7 @@ ospf_hello_send(struct ospf_iface *ifa, int kind, struct ospf_neighbor *dirn) } i = 0; - max = (ospf_pkt_bufsize(ifa) - length) / sizeof(u32); + max = (ospf_pkt_maxsize(ifa) - length) / sizeof(u32); /* Fill all neighbors */ if (kind != OHS_SHUTDOWN) @@ -309,7 +329,7 @@ ospf_hello_send(struct ospf_iface *ifa, int kind, struct ospf_neighbor *dirn) { if (i == max) { - log(L_WARN "%s: Too many neighbors on interface %s", p->name, ifa->iface->name); + log(L_WARN "%s: Too many neighbors on interface %s", p->name, ifa->ifname); break; } neighbors[i] = htonl(neigh->rid); @@ -374,6 +394,5 @@ ospf_hello_send(struct ospf_iface *ifa, int kind, struct ospf_neighbor *dirn) bug("Bug in ospf_hello_send()"); } - OSPF_TRACE(D_PACKETS, "HELLO packet sent via %s%s", - (ifa->type == OSPF_IT_VLINK ? "vlink-" : ""), ifa->iface->name); + OSPF_TRACE(D_PACKETS, "HELLO packet sent via %s", ifa->ifname); } diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 55331697..89e8fcf3 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -2,8 +2,8 @@ * BIRD -- OSPF * * (c) 1999--2005 Ondrej Filip - * (c) 2009--2012 Ondrej Zajicek - * (c) 2009--2012 CZ.NIC z.s.p.o. + * (c) 2009--2014 Ondrej Zajicek + * (c) 2009--2014 CZ.NIC z.s.p.o. * * Can be freely distributed and used under the terms of the GNU GPL. */ @@ -12,14 +12,8 @@ #define _BIRD_OSPF_H_ +#define OSPF_MIN_PKT_SIZE 256 #define OSPF_MAX_PKT_SIZE 65535 -/* - * RFC 2328 says, maximum packet size is 65535 (IP packet size - * limit). Really a bit less for OSPF, because this contains also IP - * header. This could be too much for small systems, so I normally - * allocate 2*mtu (i found one cisco sending packets mtu+16). OSPF - * packets are almost always sent small enough to not be fragmented. - */ #ifdef LOCAL_DEBUG #define OSPF_FORCE_DEBUG 1 @@ -33,7 +27,7 @@ do { if ((po->proto.debug & flags) || OSPF_FORCE_DEBUG) \ #define OSPF_PACKET(dumpfn, buffer, msg, args...) \ do { if ((po->proto.debug & D_PACKETS) || OSPF_FORCE_DEBUG) \ -{ log(L_TRACE "%s: " msg, po->proto.name, ## args ); dumpfn(po, buffer); } } while(0) + { log(L_TRACE "%s: " msg, po->proto.name, ## args ); dumpfn(po, buffer); } } while(0) #include "nest/bird.h" @@ -50,6 +44,7 @@ do { if ((po->proto.debug & D_PACKETS) || OSPF_FORCE_DEBUG) \ #include "nest/route.h" #include "nest/cli.h" #include "nest/locks.h" +#include "nest/bfd.h" #include "conf/conf.h" #include "lib/string.h" @@ -65,6 +60,8 @@ do { if ((po->proto.debug & D_PACKETS) || OSPF_FORCE_DEBUG) \ #define OSPF_DEFAULT_ECMP_LIMIT 16 #define OSPF_DEFAULT_TRANSINT 40 +#define OSPF_VLINK_ID_OFFSET 0x80000000 + struct ospf_config { @@ -73,8 +70,9 @@ struct ospf_config byte ospf2; byte rfc1583; byte stub_router; + byte merge_external; byte abr; - byte ecmp; + int ecmp; list area_list; /* list of struct ospf_area_config */ list vlink_list; /* list of struct ospf_iface_patt */ }; @@ -174,12 +172,14 @@ struct ospf_area_config struct ospf_iface { node n; - struct iface *iface; /* Nest's iface, non-NULL (unless type OSPF_IT_VLINK) */ + struct iface *iface; /* Nest's iface (NULL for vlinks) */ struct ifa *addr; /* IP prefix associated with that OSPF iface */ struct ospf_area *oa; struct ospf_iface_patt *cf; + char *ifname; /* Interface name (iface->name), new one for vlinks */ + pool *pool; - sock *sk; /* IP socket (for DD ...) */ + sock *sk; /* IP socket */ list neigh_list; /* List of neigbours */ u32 cost; /* Cost of iface */ u32 waitint; /* number of sec before changing state from wait */ @@ -245,10 +245,12 @@ struct ospf_iface u8 sk_dr; /* Socket is a member of designated routers group */ u8 marked; /* Used in OSPF reconfigure */ u16 rxbuf; /* Buffer size */ + u16 tx_length; /* Soft TX packet length limit, usually MTU */ u8 check_link; /* Whether iface link change is used */ u8 ecmp_weight; /* Weight used for ECMP */ u8 ptp_netmask; /* Send real netmask for P2P */ u8 check_ttl; /* Check incoming packets for TTL 255 */ + u8 bfd; /* Use BFD on iface */ }; struct ospf_md5 @@ -617,8 +619,7 @@ struct ospf_neighbor u32 options; /* Options received */ /* Entries dr and bdr store IP addresses in OSPFv2 and router IDs in - * OSPFv3, we use the same type to simplify handling - */ + OSPFv3, we use the same type to simplify handling */ u32 dr; /* Neigbour's idea of DR */ u32 bdr; /* Neigbour's idea of BDR */ u32 iface_id; /* ID of Neighbour's iface connected to common network */ @@ -640,12 +641,14 @@ struct ospf_neighbor slist lsrtl; /* slist of struct top_hash_entry from n->lsrth */ struct top_graph *lsrth; - void *ldbdes; /* Last database description packet */ timer *rxmt_timer; /* RXMT timer */ list ackl[2]; #define ACKL_DIRECT 0 #define ACKL_DELAY 1 timer *ackd_timer; /* Delayed ack timer */ + struct bfd_request *bfd_req; /* BFD request, if BFD is used */ + void *ldd_buffer; /* Last database description packet */ + u32 ldd_bsize; /* Buffer size for ldd_buffer */ u32 csn; /* Last received crypt seq number (for MD5) */ }; @@ -713,12 +716,14 @@ struct proto_ospf byte ospf2; /* OSPF v2 or v3 */ byte rfc1583; /* RFC1583 compatibility */ byte stub_router; /* Do not forward transit traffic */ + byte merge_external; /* Should i merge external routes? */ byte ebit; /* Did I originate any ext lsa? */ byte ecmp; /* Maximal number of nexthops in ECMP route, or 0 */ struct ospf_area *backbone; /* If exists */ void *lsab; /* LSA buffer used when originating router LSAs */ int lsab_size, lsab_used; linpool *nhpool; /* Linpool used for next hops computed in SPF */ + sock *vlink_sk; /* IP socket used for vlink TX */ u32 router_id; u32 last_vlink_id; /* Interface IDs for vlinks (starts at 0x80000000) */ }; @@ -742,9 +747,9 @@ struct ospf_iface_patt u32 vid; int tx_tos; int tx_priority; - u16 rxbuf; -#define OSPF_RXBUF_NORMAL 0 -#define OSPF_RXBUF_LARGE 1 + u16 tx_length; + u16 rx_buffer; + #define OSPF_RXBUF_MINSIZE 256 /* Minimal allowed size */ u16 autype; /* Not really used in OSPFv3 */ #define OSPF_AUTH_NONE 0 @@ -757,6 +762,8 @@ struct ospf_iface_patt u8 real_bcast; /* Not really used in OSPFv3 */ u8 ptp_netmask; /* bool + 2 for unspecified */ u8 ttl_security; /* bool + 2 for TX only */ + u8 bfd; + u8 bsd_secondary; u8 instance_id; list *passwords; };