From 47c447c42e0bfa1836d951d1e6c1a2236d39dcbb Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Fri, 4 May 2012 23:05:47 +0200 Subject: [PATCH 1/3] Minor cleanups. --- nest/rt-table.c | 5 +---- proto/bgp/packets.c | 3 --- proto/rip/rip.c | 5 ++--- sysdep/linux/sysio.h | 2 +- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/nest/rt-table.c b/nest/rt-table.c index bb0ee4c8..fdc767e7 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -799,10 +799,7 @@ void rte_dump(rte *e) { net *n = e->net; - if (n) - debug("%-1I/%2d ", n->n.prefix, n->n.pxlen); - else - debug("??? "); + debug("%-1I/%2d ", n->n.prefix, n->n.pxlen); debug("KF=%02x PF=%02x pref=%d lm=%d ", n->n.flags, e->pflags, e->pref, now-e->lastmod); rta_dump(e->attrs); if (e->attrs->proto->proto->dump_attrs) diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 168025d0..cfa37fb5 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -1031,9 +1031,6 @@ bgp_do_rx_update(struct bgp_conn *conn, if (n = net_find(p->p.table, prefix, pxlen)) rte_update(p->p.table, n, &p->p, &p->p, NULL); } - - if (bgp_apply_limits(p) < 0) - goto done; } } diff --git a/proto/rip/rip.c b/proto/rip/rip.c index b41c3f8d..281296a5 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -624,7 +624,6 @@ rip_dump(struct proto *p) int i; node *w; struct rip_interface *rif; - i = 0; CHK_MAGIC; WALK_LIST( w, P->connections ) { @@ -995,8 +994,8 @@ static int rip_get_attr(eattr *a, byte *buf, int buflen UNUSED) { switch (a->id) { - case EA_RIP_METRIC: buf += bsprintf( buf, "metric: %d", a->u.data ); return GA_FULL; - case EA_RIP_TAG: buf += bsprintf( buf, "tag: %d", a->u.data ); return GA_FULL; + case EA_RIP_METRIC: bsprintf( buf, "metric: %d", a->u.data ); return GA_FULL; + case EA_RIP_TAG: bsprintf( buf, "tag: %d", a->u.data ); return GA_FULL; default: return GA_UNKNOWN; } } diff --git a/sysdep/linux/sysio.h b/sysdep/linux/sysio.h index 705a20ae..90b3ebd9 100644 --- a/sysdep/linux/sysio.h +++ b/sysdep/linux/sysio.h @@ -301,7 +301,7 @@ sk_set_min_ttl6(sock *s, int ttl) if (errno == ENOPROTOOPT) log(L_ERR "Kernel does not support IPv6 TTL security"); else - log(L_ERR "sk_set_min_ttl4: setsockopt: %m"); + log(L_ERR "sk_set_min_ttl6: setsockopt: %m"); return -1; } From 0ec031f7400fbacdd86b40ae1870c58715a7f108 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Fri, 11 May 2012 18:52:59 +0200 Subject: [PATCH 2/3] Allows to set instance ID for OSPFv3 interfaces. --- doc/bird.sgml | 19 ++++++++++++------- proto/ospf/config.Y | 25 ++++++++++++++++++++----- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/doc/bird.sgml b/doc/bird.sgml index 3edd6e0e..820ebaa2 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1811,7 +1811,7 @@ protocol ospf <name> { summary <switch>; cost <num>; } - interface <interface pattern> { + interface <interface pattern> [instance <num>] { cost <num>; stub <switch>; hello <num>; @@ -1841,7 +1841,7 @@ protocol ospf <name> { <ip> eligible; }; }; - virtual link <id> { + virtual link <id> [instance <num>] { hello <num>; retransmit <num>; wait <num>; @@ -1961,14 +1961,19 @@ protocol ospf <name> { subnetworks of given stub network are suppressed. This might be used, for example, to aggregate generated stub networks. - interface pattern + interface pattern [instance Defines that the specified interfaces belong to the area being defined. See common option for detailed description. + In OSPFv3, you can specify instance ID for that interface + description, so it is possible to have several instances of + that interface with different options or even in different areas. - virtual link id - Virtual link to router with the router id. Virtual link acts as a - point-to-point interface belonging to backbone. The actual area is - used as transport area. This item cannot be in the backbone. + virtual link id [instance + Virtual link to router with the router id. Virtual link acts + as a point-to-point interface belonging to backbone. The + actual area is used as transport area. This item cannot be in + the backbone. In OSPFv3, you could also use several virtual + links to one destination with different instance IDs. cost num Specifies output cost (metric) of an interface. Default value is 10. diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y index 38e59886..0c36b7f8 100644 --- a/proto/ospf/config.Y +++ b/proto/ospf/config.Y @@ -107,7 +107,17 @@ static inline void check_defcost(int cost) { if ((cost <= 0) || (cost >= LSINFINITY)) - cf_error("Default cost must be in range 1-%d", LSINFINITY); + cf_error("Default cost must be in range 1-%d", LSINFINITY-1); +} + +static inline void +set_instance_id(unsigned id) +{ +#ifdef OSPFv3 + OSPF_PATT->instance_id = id; +#else + cf_error("Instance ID requires OSPFv3"); +#endif } CF_DECLS @@ -120,7 +130,7 @@ CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC) CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK) CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY, TAG, EXTERNAL) CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT, NSSA, TRANSLATOR, STABILITY) -CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF) +CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF, INSTANCE) %type opttext %type lsadb_args @@ -218,8 +228,8 @@ ospf_stubnet_item: ; ospf_vlink: - ospf_vlink_start '{' ospf_vlink_opts '}' { ospf_iface_finish(); } - | ospf_vlink_start { ospf_iface_finish(); } + ospf_vlink_start ospf_instance_id '{' ospf_vlink_opts '}' { ospf_iface_finish(); } + | ospf_vlink_start ospf_instance_id { ospf_iface_finish(); } ; ospf_vlink_opts: @@ -364,6 +374,11 @@ ospf_iface_start: } ; +ospf_instance_id: + /* empty */ + | INSTANCE expr { set_instance_id($2); } + ; + ospf_iface_opts: /* empty */ | ospf_iface_opts ospf_iface_item ';' @@ -375,7 +390,7 @@ ospf_iface_opt_list: ; ospf_iface: - ospf_iface_start iface_patt_list ospf_iface_opt_list { ospf_iface_finish(); } + ospf_iface_start iface_patt_list ospf_instance_id ospf_iface_opt_list { ospf_iface_finish(); } ; opttext: From 95127cbbb76e8870e029454a5313bc4b6ce69a4a Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Mon, 14 May 2012 11:47:41 +0200 Subject: [PATCH 3/3] Real broadcast mode for OSPFv2. --- doc/bird.sgml | 11 +++++++++++ proto/ospf/config.Y | 3 ++- proto/ospf/hello.c | 2 +- proto/ospf/iface.c | 44 +++++++++++++++++++++++++++++++------------- proto/ospf/lsack.c | 8 ++++++-- proto/ospf/lsupd.c | 6 ++++-- proto/ospf/ospf.h | 12 +++++++----- proto/ospf/packet.c | 5 ++++- proto/ospf/packet.h | 2 ++ 9 files changed, 68 insertions(+), 25 deletions(-) diff --git a/doc/bird.sgml b/doc/bird.sgml index 820ebaa2..b43eb263 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1825,6 +1825,7 @@ protocol ospf <name> { type [broadcast|bcast|pointopoint|ptp| nonbroadcast|nbma|pointomultipoint|ptmp]; strict nonbroadcast <switch>; + real broadcast <switch>; check link <switch>; ecmp weight <num>; authentication [none|simple|cryptographic]; @@ -2058,6 +2059,16 @@ protocol ospf <name> { If set, don't send hello to any undefined neighbor. This switch is ignored on other than NBMA or PtMP networks. Default value is no. + real broadcast + In check link switch If set, a hardware link state (reported by OS) is taken into consideration. When a link disappears (e.g. an ethernet cable is diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y index 0c36b7f8..67b0785f 100644 --- a/proto/ospf/config.Y +++ b/proto/ospf/config.Y @@ -130,7 +130,7 @@ CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC) CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK) CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY, TAG, EXTERNAL) CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT, NSSA, TRANSLATOR, STABILITY) -CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF, INSTANCE) +CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF, INSTANCE, REAL) %type opttext %type lsadb_args @@ -287,6 +287,7 @@ ospf_iface_item: | TYPE PTP { OSPF_PATT->type = OSPF_IT_PTP ; } | TYPE POINTOMULTIPOINT { OSPF_PATT->type = OSPF_IT_PTMP ; } | TYPE PTMP { OSPF_PATT->type = OSPF_IT_PTMP ; } + | REAL BROADCAST bool { OSPF_PATT->real_bcast = $3; if (OSPF_VERSION != 2) cf_error("Real broadcast option requires OSPFv2"); } | TRANSMIT DELAY expr { OSPF_PATT->inftransdelay = $3 ; if (($3<=0) || ($3>65535)) cf_error("Transmit delay must be in range 1-65535"); } | PRIORITY expr { OSPF_PATT->priority = $2 ; if (($2<0) || ($2>255)) cf_error("Priority must be in range 0-255"); } | STRICT NONBROADCAST bool { OSPF_PATT->strictnbma = $3 ; } diff --git a/proto/ospf/hello.c b/proto/ospf/hello.c index d04cb54c..f9ba28f6 100644 --- a/proto/ospf/hello.c +++ b/proto/ospf/hello.c @@ -303,7 +303,7 @@ ospf_hello_send(struct ospf_iface *ifa, int kind, struct ospf_neighbor *dirn) { case OSPF_IT_BCAST: case OSPF_IT_PTP: - ospf_send_to(ifa, AllSPFRouters); + ospf_send_to_all(ifa); break; case OSPF_IT_NBMA: diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c index 405e49df..a6a0c6c1 100644 --- a/proto/ospf/iface.c +++ b/proto/ospf/iface.c @@ -120,13 +120,24 @@ ospf_sk_open(struct ospf_iface *ifa) sk->saddr = ifa->addr->ip; if ((ifa->type == OSPF_IT_BCAST) || (ifa->type == OSPF_IT_PTP)) { - sk->ttl = 1; /* Hack, this will affect just multicast packets */ + if (ifa->cf->real_bcast) + { + ifa->all_routers = ifa->addr->brd; - if (sk_setup_multicast(sk) < 0) - goto err; + if (sk_set_broadcast(sk, 1) < 0) + goto err; + } + else + { + ifa->all_routers = AllSPFRouters; + sk->ttl = 1; /* Hack, this will affect just multicast packets */ - if (sk_join_group(sk, AllSPFRouters) < 0) - goto err; + if (sk_setup_multicast(sk) < 0) + goto err; + + if (sk_join_group(sk, ifa->all_routers) < 0) + goto err; + } } ifa->sk = sk; @@ -265,7 +276,7 @@ ospf_iface_chstate(struct ospf_iface *ifa, u8 state) OSPF_TRACE(D_EVENTS, "Changing state of iface %s from %s to %s", ifa->iface->name, ospf_is[oldstate], ospf_is[state]); - if ((ifa->type == OSPF_IT_BCAST) && ifa->sk) + if ((ifa->type == OSPF_IT_BCAST) && !ifa->cf->real_bcast && ifa->sk) { if ((state == OSPF_IS_BACKUP) || (state == OSPF_IS_DR)) ospf_sk_join_dr(ifa); @@ -536,6 +547,7 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i /* Check validity of interface type */ int old_type = ifa->type; + u32 if_multi_flag = ip->real_bcast ? IF_BROADCAST : IF_MULTICAST; #ifdef OSPFv2 if ((ifa->type == OSPF_IT_BCAST) && (addr->flags & IA_PEER)) @@ -545,10 +557,10 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i ifa->type = OSPF_IT_PTMP; #endif - if ((ifa->type == OSPF_IT_BCAST) && !(iface->flags & IF_MULTICAST)) + if ((ifa->type == OSPF_IT_BCAST) && !(iface->flags & if_multi_flag)) ifa->type = OSPF_IT_NBMA; - if ((ifa->type == OSPF_IT_PTP) && !(iface->flags & IF_MULTICAST)) + if ((ifa->type == OSPF_IT_PTP) && !(iface->flags & if_multi_flag)) ifa->type = OSPF_IT_PTMP; if (ifa->type != old_type) @@ -628,6 +640,9 @@ ospf_iface_reconfigure(struct ospf_iface *ifa, struct ospf_iface_patt *new) if (ifa->stub != new_stub) return 0; + if (new->real_bcast != ifa->cf->real_bcast) + return 0; + ifa->cf = new; ifa->marked = 0; @@ -1099,11 +1114,15 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface) void ospf_iface_info(struct ospf_iface *ifa) { - char *strict = ""; + char *more = ""; if (ifa->strictnbma && ((ifa->type == OSPF_IT_NBMA) || (ifa->type == OSPF_IT_PTMP))) - strict = "(strict)"; + more = " (strict)"; + + if (ifa->cf->real_bcast && + ((ifa->type == OSPF_IT_BCAST) || (ifa->type == OSPF_IT_PTP))) + more = " (real)"; if (ifa->type == OSPF_IT_VLINK) { @@ -1124,11 +1143,10 @@ ospf_iface_info(struct ospf_iface *ifa) #else /* OSPFv3 */ cli_msg(-1015, "Interface %s (IID %d)", ifa->iface->name, ifa->instance_id); #endif - cli_msg(-1015, "\tType: %s %s", ospf_it[ifa->type], strict); + cli_msg(-1015, "\tType: %s%s", ospf_it[ifa->type], more); cli_msg(-1015, "\tArea: %R (%u)", ifa->oa->areaid, ifa->oa->areaid); } - cli_msg(-1015, "\tState: %s %s", ospf_is[ifa->state], - ifa->stub ? "(stub)" : ""); + cli_msg(-1015, "\tState: %s%s", ospf_is[ifa->state], ifa->stub ? " (stub)" : ""); cli_msg(-1015, "\tPriority: %u", ifa->priority); cli_msg(-1015, "\tCost: %u", ifa->cost); if (ifa->oa->po->ecmp) diff --git a/proto/ospf/lsack.c b/proto/ospf/lsack.c index 53422e53..00c50caf 100644 --- a/proto/ospf/lsack.c +++ b/proto/ospf/lsack.c @@ -97,7 +97,9 @@ ospf_lsack_send(struct ospf_neighbor *n, int queue) if (ifa->type == OSPF_IT_BCAST) { if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP)) - ospf_send_to(ifa, AllSPFRouters); + ospf_send_to_all(ifa); + else if (ifa->cf->real_bcast) + ospf_send_to_bdr(ifa); else ospf_send_to(ifa, AllDRouters); } @@ -124,7 +126,9 @@ ospf_lsack_send(struct ospf_neighbor *n, int queue) if (ifa->type == OSPF_IT_BCAST) { if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP)) - ospf_send_to(ifa, AllSPFRouters); + ospf_send_to_all(ifa); + else if (ifa->cf->real_bcast) + ospf_send_to_bdr(ifa); else ospf_send_to(ifa, AllDRouters); } diff --git a/proto/ospf/lsupd.c b/proto/ospf/lsupd.c index 325a8d00..f71c72d1 100644 --- a/proto/ospf/lsupd.c +++ b/proto/ospf/lsupd.c @@ -314,7 +314,9 @@ ospf_lsupd_flood(struct proto_ospf *po, { case OSPF_IT_BCAST: if ((ifa->state == OSPF_IS_BACKUP) || (ifa->state == OSPF_IS_DR)) - ospf_send_to(ifa, AllSPFRouters); + ospf_send_to_all(ifa); + else if (ifa->cf->real_bcast) + ospf_send_to_bdr(ifa); else ospf_send_to(ifa, AllDRouters); break; @@ -327,7 +329,7 @@ ospf_lsupd_flood(struct proto_ospf *po, break; case OSPF_IT_PTP: - ospf_send_to(ifa, AllSPFRouters); + ospf_send_to_all(ifa); break; case OSPF_IT_PTMP: diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 96da9aa7..3bffaf91 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -205,6 +205,7 @@ struct ospf_iface bird_clock_t csn_use; /* Last time when packet with that CSN was sent */ #endif + ip_addr all_routers; /* */ ip_addr drip; /* Designated router */ ip_addr bdrip; /* Backup DR */ u32 drid; @@ -790,22 +791,23 @@ struct ospf_iface_patt u32 deadc; u32 deadint; u32 inftransdelay; - u32 priority; - u32 strictnbma; list nbma_list; + u32 priority; u32 voa; u32 vid; u16 rxbuf; - u8 check_link; - u8 ecmp_weight; #define OSPF_RXBUF_NORMAL 0 #define OSPF_RXBUF_LARGE 1 #define OSPF_RXBUF_MINSIZE 256 /* Minimal allowed size */ - u32 autype; /* Not really used in OSPFv3 */ + u16 autype; /* Not really used in OSPFv3 */ #define OSPF_AUTH_NONE 0 #define OSPF_AUTH_SIMPLE 1 #define OSPF_AUTH_CRYPT 2 #define OSPF_AUTH_CRYPT_SIZE 16 + u8 strictnbma; + u8 check_link; + u8 ecmp_weight; + u8 real_bcast; /* Not really used in OSPFv3 */ #ifdef OSPFv2 list *passwords; diff --git a/proto/ospf/packet.c b/proto/ospf/packet.c index 7a26967f..241a58f7 100644 --- a/proto/ospf/packet.c +++ b/proto/ospf/packet.c @@ -273,7 +273,7 @@ ospf_rx_hook(sock *sk, int size) int src_local, dst_local UNUSED, dst_mcast; src_local = ipa_in_net(sk->faddr, ifa->addr->prefix, ifa->addr->pxlen); dst_local = ipa_equal(sk->laddr, ifa->addr->ip); - dst_mcast = ipa_equal(sk->laddr, AllSPFRouters) || ipa_equal(sk->laddr, AllDRouters); + dst_mcast = ipa_equal(sk->laddr, ifa->all_routers) || ipa_equal(sk->laddr, AllDRouters); #ifdef OSPFv2 /* First, we eliminate packets with strange address combinations. @@ -287,6 +287,9 @@ ospf_rx_hook(sock *sk, int size) if (!dst_mcast && !dst_local) return 1; + /* Ignore my own broadcast packets */ + if (ifa->cf->real_bcast && ipa_equal(sk->faddr, ifa->addr->ip)) + return 1; #else /* OSPFv3 */ /* In OSPFv3, src_local and dst_local mean link-local. diff --git a/proto/ospf/packet.h b/proto/ospf/packet.h index c0185b9c..fbcb4288 100644 --- a/proto/ospf/packet.h +++ b/proto/ospf/packet.h @@ -19,6 +19,8 @@ void ospf_send_to_agt(struct ospf_iface *ifa, u8 state); void ospf_send_to_bdr(struct ospf_iface *ifa); void ospf_send_to(struct ospf_iface *ifa, ip_addr ip); +static inline void ospf_send_to_all(struct ospf_iface *ifa) { ospf_send_to(ifa, ifa->all_routers); } + static inline void * ospf_tx_buffer(struct ospf_iface *ifa) { return ifa->sk->tbuf; } static inline unsigned