From 23c212e7f1e80a3c6b88b49918972bc28375bd51 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Mon, 21 Dec 2015 03:27:41 +0100 Subject: [PATCH] Follow-up work on integration --- filter/config.Y | 2 -- lib/net.c | 6 +++--- lib/net.h | 8 ++++---- lib/printf.c | 14 +++++++------- lib/socket.h | 16 ++++++---------- lib/unaligned.h | 1 + nest/iface.c | 4 +--- nest/rt-fib.c | 11 +++++++---- proto/ospf/config.Y | 14 ++++++++++---- proto/ospf/ospf.c | 3 +++ proto/ospf/ospf.h | 14 +------------- proto/ospf/rt.c | 2 +- proto/rip/config.Y | 13 +++++++++---- proto/rip/packets.c | 3 ++- proto/rip/rip.c | 6 +++++- proto/rip/rip.h | 12 +----------- sysdep/linux/netlink.c | 21 ++++++++++----------- tools/Makefile.in | 8 ++++---- 18 files changed, 75 insertions(+), 83 deletions(-) diff --git a/filter/config.Y b/filter/config.Y index 92ac6fa5..7e9f4104 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -205,7 +205,6 @@ f_generate_ec(u16 kind, struct f_inst *tk, struct f_inst *tv) cf_error("Can't operate with key of non-integer/IPv4 type in EC constructor"); } -#ifndef IPV6 /* IP->Quad implicit conversion */ else if (tk->code == 'C') { c1 = 1; @@ -223,7 +222,6 @@ f_generate_ec(u16 kind, struct f_inst *tk, struct f_inst *tv) else cf_error("Can't operate with key of non-integer/IPv4 type in EC constructor"); } -#endif if (tv->code == 'c') { if (tv->aux != T_INT) diff --git a/lib/net.c b/lib/net.c index b851871a..09f23c7a 100644 --- a/lib/net.c +++ b/lib/net.c @@ -31,15 +31,15 @@ net_format(const net_addr *N, char *buf, int buflen) { net_addr_union *n = (void *) N; - /* FIXME: quick hack */ + /* XXXX fix %I vs %R */ switch (n->n.type) { case NET_IP4: - return bsnprintf(buf, buflen, "%I/%d", n->ip4.prefix, n->ip4.pxlen); + return bsnprintf(buf, buflen, "%R/%d", n->ip4.prefix, n->ip4.pxlen); case NET_IP6: return bsnprintf(buf, buflen, "%I/%d", n->ip6.prefix, n->ip6.pxlen); case NET_VPN4: - return bsnprintf(buf, buflen, "%u:%u %I/%d", (u32) (n->vpn4.rd >> 32), (u32) n->vpn4.rd, n->vpn4.prefix, n->vpn4.pxlen); + return bsnprintf(buf, buflen, "%u:%u %R/%d", (u32) (n->vpn4.rd >> 32), (u32) n->vpn4.rd, n->vpn4.prefix, n->vpn4.pxlen); case NET_VPN6: return bsnprintf(buf, buflen, "%u:%u %I/%d", (u32) (n->vpn6.rd >> 32), (u32) n->vpn6.rd, n->vpn6.prefix, n->vpn6.pxlen); } diff --git a/lib/net.h b/lib/net.h index ee9b382e..9439c6db 100644 --- a/lib/net.h +++ b/lib/net.h @@ -199,20 +199,20 @@ static inline void net_copy_vpn6(net_addr_vpn6 *dst, const net_addr_vpn6 *src) static inline u32 net_hash_ip4(const net_addr_ip4 *n) -{ return ip4_hash(n->prefix) ^ ((u32) n->pxlen << 26); } +{ return ip4_hash32(n->prefix) ^ ((u32) n->pxlen << 26); } static inline u32 net_hash_ip6(const net_addr_ip6 *n) -{ return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26); } +{ return ip6_hash32(n->prefix) ^ ((u32) n->pxlen << 26); } /* XXXX */ static inline u32 u64_hash(u32 a) { return u32_hash(a); } static inline u32 net_hash_vpn4(const net_addr_vpn4 *n) -{ return ip4_hash(n->prefix) ^ ((u32) n->pxlen << 26) ^ u64_hash(n->rd); } +{ return ip4_hash32(n->prefix) ^ ((u32) n->pxlen << 26) ^ u64_hash(n->rd); } static inline u32 net_hash_vpn6(const net_addr_vpn6 *n) -{ return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26) ^ u64_hash(n->rd); } +{ return ip6_hash32(n->prefix) ^ ((u32) n->pxlen << 26) ^ u64_hash(n->rd); } static inline int net_validate_ip4(const net_addr_ip4 *n) diff --git a/lib/printf.c b/lib/printf.c index 9db5363b..071fc953 100644 --- a/lib/printf.c +++ b/lib/printf.c @@ -292,9 +292,13 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args) case 'I': { ip_addr a = va_arg(args, ip_addr); if (flags & SPECIAL) - ipa_ntox(a, ipbuf); + ip6_ntox(ipa_to_ip6(a), ipbuf); else { - ipa_ntop(a, ipbuf); + // XXXX better IPv4 / IPv6 distinction + if (ipa_is_ip4(a)) + ip4_ntop(ipa_to_ip4(a), ipbuf); + else + ip6_ntop(ipa_to_ip6(a), ipbuf); if (field_width == 1) field_width = (ipa_is_ip4(a) ? IP4_MAX_TEXT_LENGTH : IP6_MAX_TEXT_LENGTH); } @@ -319,11 +323,7 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args) /* Router/Network ID - essentially IPv4 address in u32 value */ case 'R': x = va_arg(args, u32); - bsprintf(ipbuf, "%d.%d.%d.%d", - ((x >> 24) & 0xff), - ((x >> 16) & 0xff), - ((x >> 8) & 0xff), - (x & 0xff)); + ip4_ntop(ip4_from_u32(x), ipbuf); s = ipbuf; goto str; diff --git a/lib/socket.h b/lib/socket.h index fbea92aa..b067eb54 100644 --- a/lib/socket.h +++ b/lib/socket.h @@ -67,19 +67,15 @@ void sk_set_tbsize(sock *s, uint val); /* Resize TX buffer, keeping content */ void sk_set_tbuf(sock *s, void *tbuf); /* Switch TX buffer, NULL-> return to internal */ void sk_dump_all(void); +static inline int sk_is_ipv4(sock *s) +{ return s->af == AF_INET; } + +static inline int sk_is_ipv6(sock *s) +{ return s->af == AF_INET6; } + static inline int sk_send_buffer_empty(sock *sk) { return sk->tbuf == sk->tpos; } - -#ifdef IPV6 -#define sk_is_ipv4(X) 0 -#define sk_is_ipv6(X) 1 -#else -#define sk_is_ipv4(X) 1 -#define sk_is_ipv6(X) 0 -#endif - - int sk_setup_multicast(sock *s); /* Prepare UDP or IP socket for multicasting */ int sk_join_group(sock *s, ip_addr maddr); /* Join multicast group on sk iface */ int sk_leave_group(sock *s, ip_addr maddr); /* Leave multicast group on sk iface */ diff --git a/lib/unaligned.h b/lib/unaligned.h index dc777fbf..130b2479 100644 --- a/lib/unaligned.h +++ b/lib/unaligned.h @@ -17,6 +17,7 @@ * if possible. */ +#include "lib/endian.h" #include "lib/string.h" static inline u16 diff --git a/nest/iface.c b/nest/iface.c index 3eaa5ebd..e9f55f0a 100644 --- a/nest/iface.c +++ b/nest/iface.c @@ -532,10 +532,8 @@ ifa_update(struct ifa *a) break; } -#ifndef IPV6 - if ((i->flags & IF_BROADCAST) && !ipa_nonzero(a->brd)) + if ((a->prefix.type == NET_IP4) && (i->flags & IF_BROADCAST) && ipa_zero(a->brd)) log(L_ERR "Missing broadcast address for interface %s", i->name); -#endif b = mb_alloc(if_pool, sizeof(struct ifa)); memcpy(b, a, sizeof(struct ifa)); diff --git a/nest/rt-fib.c b/nest/rt-fib.c index ff7f5c00..474236e0 100644 --- a/nest/rt-fib.c +++ b/nest/rt-fib.c @@ -59,7 +59,7 @@ static void fib_ht_alloc(struct fib *f) { f->hash_size = 1 << f->hash_order; - f->hash_shift = 16 - f->hash_order; + f->hash_shift = 32 - f->hash_order; if (f->hash_order > HASH_HI_MAX - HASH_HI_STEP) f->entries_max = ~0; else @@ -168,7 +168,7 @@ fib_rehash(struct fib *f, int step) struct fib_node *e = f->hash_table[FIB_HASH(f, a, t)]; \ while (e && !net_equal_##t(CAST(t) e->addr, CAST(t) a)) \ e = e->next; \ - fib_node_to_user(f, e); \ + e ? fib_node_to_user(f, e) : NULL; \ }) #define FIB_INSERT(f,a,e,t) \ @@ -247,7 +247,7 @@ fib_insert(struct fib *f, const net_addr *a, struct fib_node *e) void * fib_get(struct fib *f, const net_addr *a) { - char *b = fib_find(f, a); + void *b = fib_find(f, a); if (b) return b; @@ -256,7 +256,7 @@ fib_get(struct fib *f, const net_addr *a) else b = mb_alloc(f->fib_pool, f->node_size + a->length); - struct fib_node *e = (void *) (b + f->node_offset); + struct fib_node *e = fib_user_to_node(f, b); e->readers = NULL; e->flags = 0; e->uid = 0; @@ -522,6 +522,7 @@ found: void fib_check(struct fib *f) { +#if 0 uint i, ec, lo, nulls; ec = 0; @@ -557,6 +558,8 @@ fib_check(struct fib *f) } if (ec != f->entries) bug("fib_check: invalid entry count (%d != %d)", ec, f->entries); +#endif + return; } /* diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y index e8fb7f2e..6d8fa755 100644 --- a/proto/ospf/config.Y +++ b/proto/ospf/config.Y @@ -130,21 +130,27 @@ CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK, ONLY, BFD) 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, REAL, NETMASK, TX, PRIORITY, LENGTH) -CF_KEYWORDS(SECONDARY, MERGE, LSA, SUPPRESSION) +CF_KEYWORDS(SECONDARY, MERGE, LSA, SUPPRESSION, OSPF2, OSPF3) %type lsadb_args -%type nbma_eligible +%type ospf_variant nbma_eligible CF_GRAMMAR CF_ADDTO(proto, ospf_proto '}' { ospf_proto_finish(); } ) -ospf_proto_start: proto_start OSPF { +ospf_variant: + OSPF { $$ = 1; } + | OSPF2 { $$ = 1; } + | OSPF3 { $$ = 0; } + ; + +ospf_proto_start: proto_start ospf_variant { this_proto = proto_config_new(&proto_ospf, $1); init_list(&OSPF_CFG->area_list); init_list(&OSPF_CFG->vlink_list); OSPF_CFG->tick = OSPF_DEFAULT_TICK; - OSPF_CFG->ospf2 = OSPF_IS_V2; + OSPF_CFG->ospf2 = $2; } ; diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 983f76f1..8008e4d8 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -648,6 +648,9 @@ ospf_reconfigure(struct proto *P, struct proto_config *c) if (proto_get_router_id(c) != p->router_id) return 0; + if (p->ospf2 != new->ospf2) + return 0; + if (p->rfc1583 != new->rfc1583) return 0; diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 3e96b511..f4f91de1 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -37,14 +37,6 @@ #endif -#ifdef IPV6 -#define OSPF_IS_V2 0 -#else -#define OSPF_IS_V2 1 -#endif - -// FIXME: MAX_PREFIX_LENGTH - #define OSPF_TRACE(flags, msg, args...) \ do { if ((p->p.debug & flags) || OSPF_FORCE_DEBUG) \ log(L_TRACE "%s: " msg, p->p.name , ## args ); } while(0) @@ -837,16 +829,12 @@ static inline void ospf_notify_net_lsa(struct ospf_iface *ifa) static inline void ospf_notify_link_lsa(struct ospf_iface *ifa) { ifa->update_link_lsa = 1; } - -#define ospf_is_v2(X) OSPF_IS_V2 -#define ospf_is_v3(X) (!OSPF_IS_V2) -/* static inline int ospf_is_v2(struct ospf_proto *p) { return p->ospf2; } static inline int ospf_is_v3(struct ospf_proto *p) { return ! p->ospf2; } -*/ + static inline int ospf_get_version(struct ospf_proto *p) { return ospf_is_v2(p) ? 2 : 3; } diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c index 0adc3871..0031089c 100644 --- a/proto/ospf/rt.c +++ b/proto/ospf/rt.c @@ -1428,7 +1428,7 @@ loop: static void * ospf_fib_route(struct fib *f, ip_addr a) { - if (ospf_is_v2(p)) + if (f->addr_type == NET_IP4) return ospf_fib_route_ip4(f, ipa_to_ip4(a), IP4_MAX_PREFIX_LENGTH); else return ospf_fib_route_ip6(f, ipa_to_ip6(a), IP6_MAX_PREFIX_LENGTH); diff --git a/proto/rip/config.Y b/proto/rip/config.Y index 29ea7eb1..d81c42d7 100644 --- a/proto/rip/config.Y +++ b/proto/rip/config.Y @@ -32,24 +32,29 @@ rip_check_auth(void) CF_DECLS -CF_KEYWORDS(RIP, ECMP, LIMIT, WEIGHT, INFINITY, METRIC, UPDATE, TIMEOUT, +CF_KEYWORDS(RIP, RIPNG, ECMP, LIMIT, WEIGHT, INFINITY, METRIC, UPDATE, TIMEOUT, GARBAGE, PORT, ADDRESS, MODE, BROADCAST, MULTICAST, PASSIVE, VERSION, SPLIT, HORIZON, POISON, REVERSE, CHECK, ZERO, TIME, BFD, AUTHENTICATION, NONE, PLAINTEXT, CRYPTOGRAPHIC, MD5, TTL, SECURITY, RX, TX, BUFFER, LENGTH, PRIORITY, ONLY, LINK, RIP_METRIC, RIP_TAG) -%type rip_auth +%type rip_variant rip_auth CF_GRAMMAR CF_ADDTO(proto, rip_proto) -rip_proto_start: proto_start RIP +rip_variant: + RIP { $$ = 1; } + | RIPNG { $$ = 0; } + ; + +rip_proto_start: proto_start rip_variant { this_proto = proto_config_new(&proto_rip, $1); init_list(&RIP_CFG->patt_list); - RIP_CFG->rip2 = RIP_IS_V2; + RIP_CFG->rip2 = $2; RIP_CFG->infinity = RIP_DEFAULT_INFINITY; RIP_CFG->min_timeout_time = 60; diff --git a/proto/rip/packets.c b/proto/rip/packets.c index 85f0bea5..2e83a463 100644 --- a/proto/rip/packets.c +++ b/proto/rip/packets.c @@ -736,7 +736,8 @@ rip_open_socket(struct rip_iface *ifa) sk->tos = ifa->cf->tx_tos; sk->priority = ifa->cf->tx_priority; sk->ttl = ifa->cf->ttl_security ? 255 : 1; - sk->flags = SKF_LADDR_RX | ((ifa->cf->ttl_security == 1) ? SKF_TTL_RX : 0); + sk->flags = SKF_LADDR_RX | (rip_is_ng(p) ? SKF_V6ONLY : 0) | + ((ifa->cf->ttl_security == 1) ? SKF_TTL_RX : 0); /* sk->rbsize and sk->tbsize are handled in rip_iface_update_buffers() */ diff --git a/proto/rip/rip.c b/proto/rip/rip.c index d8c3b6a8..f90d7711 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -1097,11 +1097,12 @@ rip_start(struct proto *P) struct rip_config *cf = (void *) (P->cf); init_list(&p->iface_list); - fib_init(&p->rtable, P->pool, rip_is_v2(p) ? NET_IP4 : NET_IP6, + fib_init(&p->rtable, P->pool, cf->rip2 ? NET_IP4 : NET_IP6, sizeof(struct rip_entry), OFFSETOF(struct rip_entry, n), 0, NULL); p->rte_slab = sl_new(P->pool, sizeof(struct rip_rte)); p->timer = tm_new_set(P->pool, rip_timer, p, 0, 0); + p->rip2 = cf->rip2; p->ecmp = cf->ecmp; p->infinity = cf->infinity; p->triggered = 0; @@ -1121,6 +1122,9 @@ rip_reconfigure(struct proto *P, struct proto_config *c) struct rip_config *new = (void *) c; // struct rip_config *old = (void *) (P->cf); + if (new->rip2 != p->rip2) + return 0; + if (new->infinity != p->infinity) return 0; diff --git a/proto/rip/rip.h b/proto/rip/rip.h index 97c5ab3f..d1c9933c 100644 --- a/proto/rip/rip.h +++ b/proto/rip/rip.h @@ -27,12 +27,6 @@ #include "lib/timer.h" -#ifdef IPV6 -#define RIP_IS_V2 0 -#else -#define RIP_IS_V2 1 -#endif - #define RIP_V1 1 #define RIP_V2 2 @@ -98,6 +92,7 @@ struct rip_proto slab *rte_slab; /* Slab for internal routes (struct rip_rte) */ timer *timer; /* Main protocol timer */ + u8 rip2; /* RIPv2 (IPv4) or RIPng (IPv6) */ u8 ecmp; /* Maximum number of nexthops in ECMP route, or 0 */ u8 infinity; /* Maximum metric value, representing infinity */ u8 triggered; /* Logical AND of interface want_triggered values */ @@ -190,16 +185,11 @@ struct rip_rte #define EA_RIP_METRIC EA_CODE(EAP_RIP, 0) #define EA_RIP_TAG EA_CODE(EAP_RIP, 1) -#define rip_is_v2(X) RIP_IS_V2 -#define rip_is_ng(X) (!RIP_IS_V2) - -/* static inline int rip_is_v2(struct rip_proto *p) { return p->rip2; } static inline int rip_is_ng(struct rip_proto *p) { return ! p->rip2; } -*/ static inline void rip_reset_tx_session(struct rip_proto *p, struct rip_iface *ifa) diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c index 5015eba3..b3d0a9ab 100644 --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@ -477,12 +477,12 @@ nl_parse_multipath(struct krt_proto *p, struct rtattr *ra) nl_parse_attrs(RTNH_DATA(nh), mpnh_attr_want4, a, sizeof(a)); if (a[RTA_GATEWAY]) { - memcpy(&rv->gw, RTA_DATA(a[RTA_GATEWAY]), sizeof(ip_addr)); - ipa_ntoh(rv->gw); + rv->gw = rta_get_ipa(a[RTA_GATEWAY]); - neighbor *ng = neigh_find2(&p->p, &rv->gw, rv->iface, - (nh->rtnh_flags & RTNH_F_ONLINK) ? NEF_ONLINK : 0); - if (!ng || (ng->scope == SCOPE_HOST)) + neighbor *nbr; + nbr = neigh_find2(&p->p, &rv->gw, rv->iface, + (nh->rtnh_flags & RTNH_F_ONLINK) ? NEF_ONLINK : 0); + if (!nbr || (nbr->scope == SCOPE_HOST)) return NULL; } else @@ -1165,18 +1165,17 @@ nl_parse_route(struct nlmsghdr *h, int scan) if (a[RTA_GATEWAY]) { - neighbor *ng; ra.dest = RTD_ROUTER; - memcpy(&ra.gw, RTA_DATA(a[RTA_GATEWAY]), sizeof(ra.gw)); - ipa_ntoh(ra.gw); + ra.gw = rta_get_ipa(a[RTA_GATEWAY]); /* Silently skip strange 6to4 routes */ if ((i->rtm_family == AF_INET6) && ipa_in_net(ra.gw, IPA_NONE, 96)) return; - ng = neigh_find2(&p->p, &ra.gw, ra.iface, - (i->rtm_flags & RTNH_F_ONLINK) ? NEF_ONLINK : 0); - if (!ng || (ng->scope == SCOPE_HOST)) + neighbor *nbr; + nbr = neigh_find2(&p->p, &ra.gw, ra.iface, + (i->rtm_flags & RTNH_F_ONLINK) ? NEF_ONLINK : 0); + if (!nbr || (nbr->scope == SCOPE_HOST)) { log(L_ERR "KRT: Received route %N with strange next-hop %I", net->n.addr, ra.gw); return; diff --git a/tools/Makefile.in b/tools/Makefile.in index 01bb7a7c..5de323ab 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -72,15 +72,15 @@ tags: install: all $(INSTALL) -d $(DESTDIR)/$(sbindir) $(DESTDIR)/$(sysconfdir) $(DESTDIR)/@runtimedir@ - $(INSTALL_PROGRAM) $(exedir)/bird $(DESTDIR)/$(sbindir)/bird@SUFFIX@ - $(INSTALL_PROGRAM) $(exedir)/birdcl $(DESTDIR)/$(sbindir)/birdcl@SUFFIX@ + $(INSTALL_PROGRAM) $(exedir)/bird $(DESTDIR)/$(sbindir)/bird + $(INSTALL_PROGRAM) $(exedir)/birdcl $(DESTDIR)/$(sbindir)/birdcl if test -n "@CLIENT@" ; then \ - $(INSTALL_PROGRAM) $(exedir)/birdc $(DESTDIR)/$(sbindir)/birdc@SUFFIX@ ; \ + $(INSTALL_PROGRAM) $(exedir)/birdc $(DESTDIR)/$(sbindir)/birdc ; \ fi if ! test -f $(DESTDIR)/@CONFIG_FILE@ ; then \ $(INSTALL_DATA) $(srcdir)/doc/bird.conf.example $(DESTDIR)/@CONFIG_FILE@ ; \ else \ - echo "Not overwriting old bird@SUFFIX@.conf" ; \ + echo "Not overwriting old bird.conf" ; \ fi install-docs: