From 0bf95f99e6126b481a4dcac574ada59f9ad3662b Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Mon, 21 Dec 2015 17:17:21 +0100 Subject: [PATCH] Follow-up work on integration Contains some patches from Jan Moskyto Matejka --- filter/filter.c | 10 ++-- filter/filter.h | 2 +- filter/trie.c | 15 +++++- lib/birdlib.h | 6 --- lib/ip.h | 101 +---------------------------------------- lib/net.c | 27 ++++++----- nest/config.Y | 4 +- proto/ospf/config.Y | 1 - proto/ospf/iface.c | 9 ---- proto/ospf/ospf.h | 1 - sysdep/bsd/krt-sock.c | 1 + sysdep/config.h | 3 -- sysdep/linux/netlink.c | 3 +- sysdep/unix/krt.Y | 3 +- sysdep/unix/krt.c | 8 ++-- sysdep/unix/krt.h | 3 +- sysdep/unix/unix.h | 6 --- 17 files changed, 47 insertions(+), 156 deletions(-) diff --git a/filter/filter.c b/filter/filter.c index 5c0e62f9..7a5ba5b9 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -1095,11 +1095,11 @@ interpret(struct f_inst *what) runtime( "Integer expected"); if (v1.type != T_IP) runtime( "You can mask only IP addresses" ); - { - ip_addr mask = ipa_mkmask(v2.val.i); - res.type = T_IP; - res.val.ip = ipa_and(mask, v1.val.ip); - } + + res.type = T_IP; + res.val.ip = ipa_is_ip4(v1.val.ip) ? + ipa_from_ip4(ip4_and(ipa_to_ip4(v1.val.ip), ip4_mkmask(v2.val.i))) : + ipa_from_ip6(ip6_and(ipa_to_ip6(v1.val.ip), ip6_mkmask(v2.val.i))); break; case 'E': /* Create empty attribute */ diff --git a/filter/filter.h b/filter/filter.h index fe753630..1052f8c8 100644 --- a/filter/filter.h +++ b/filter/filter.h @@ -76,7 +76,7 @@ int same_tree(struct f_tree *t1, struct f_tree *t2); void tree_format(struct f_tree *t, buffer *buf); struct f_trie *f_new_trie(linpool *lp, uint node_size); -void *trie_add_prefix(struct f_trie *t, net_addr *n, uint l, uint h); +void *trie_add_prefix(struct f_trie *t, const net_addr *n, uint l, uint h); int trie_match_net(struct f_trie *t, const net_addr *n); int trie_same(struct f_trie *t1, struct f_trie *t2); void trie_format(struct f_trie *t, buffer *buf); diff --git a/filter/trie.c b/filter/trie.c index 9fdaac6d..6e234af4 100644 --- a/filter/trie.c +++ b/filter/trie.c @@ -74,6 +74,19 @@ #include "conf/conf.h" #include "filter/filter.h" + +/* + * In the trie code, the prefix length is internally treated as for the whole + * ip_addr, regardless whether it contains an IPv4 or IPv6 address. Therefore, + * remaining definitions make sense. + */ + +#define ipa_mkmask(x) ip6_mkmask(x) +#define ipa_masklen(x) ip6_masklen(&x) +#define ipa_pxlen(x,y) ip6_pxlen(x,y) +#define ipa_getbit(x,n) ip6_getbit(x,n) + + /** * f_new_trie - allocates and returns a new empty trie * @lp: linear pool to allocate items from @@ -123,7 +136,7 @@ attach_node(struct f_trie_node *parent, struct f_trie_node *child) */ void * -trie_add_prefix(struct f_trie *t, net_addr *net, uint l, uint h) +trie_add_prefix(struct f_trie *t, const net_addr *net, uint l, uint h) { ip_addr px = net_prefix(net); uint plen = net_pxlen(net); diff --git a/lib/birdlib.h b/lib/birdlib.h index 5fec6c7a..9ffe0070 100644 --- a/lib/birdlib.h +++ b/lib/birdlib.h @@ -55,12 +55,6 @@ static inline int u64_cmp(u64 i1, u64 i2) #define NULL ((void *) 0) #endif -#ifndef IPV6 -#define IP_VERSION 4 -#else -#define IP_VERSION 6 -#endif - /* Macros for gcc attributes */ diff --git a/lib/ip.h b/lib/ip.h index 7a31dad0..60a9a7b2 100644 --- a/lib/ip.h +++ b/lib/ip.h @@ -77,8 +77,6 @@ typedef struct ip6_addr { #define _I3(a) ((a).addr[3]) -#ifdef IPV6 - /* Structure ip_addr may contain both IPv4 and IPv6 addresses */ typedef ip6_addr ip_addr; #define IPA_NONE IP6_NONE @@ -93,24 +91,6 @@ typedef ip6_addr ip_addr; #define ipa_is_ip4(a) ip6_is_v4mapped(a) -#else - -/* Provisionary ip_addr definition same as ip4_addr */ -typedef ip4_addr ip_addr; -#define IPA_NONE IP4_NONE - -#define ipa_from_ip4(x) x -#define ipa_from_ip6(x) IPA_NONE -#define ipa_from_u32(x) ipa_from_ip4(ip4_from_u32(x)) - -#define ipa_to_ip4(x) x -#define ipa_to_ip6(x) IP6_NONE -#define ipa_to_u32(x) ip4_to_u32(ipa_to_ip4(x)) - -#define ipa_is_ip4(a) 1 - -#endif - /* * Public constructors @@ -174,7 +154,6 @@ static inline ip6_addr ip6_not(ip6_addr a) { return _MI6(~_I0(a), ~_I1(a), ~_I2(a), ~_I3(a)); } -#ifdef IPV6 #define ipa_equal(x,y) ip6_equal(x,y) #define ipa_zero(x) ip6_zero(x) #define ipa_nonzero(x) ip6_nonzero(x) @@ -182,19 +161,8 @@ static inline ip6_addr ip6_not(ip6_addr a) #define ipa_or(x,y) ip6_or(x,y) #define ipa_xor(x,y) ip6_xor(x,y) #define ipa_not(x) ip6_not(x) -#else -#define ipa_equal(x,y) ip4_equal(x,y) -#define ipa_zero(x) ip4_zero(x) -#define ipa_nonzero(x) ip4_nonzero(x) -#define ipa_and(x,y) ip4_and(x,y) -#define ipa_or(x,y) ip4_or(x,y) -#define ipa_xor(x,y) ip4_xor(x,y) -#define ipa_not(x) ip4_not(x) -#endif - -#ifdef IPV6 /* * A zero address is either a token for invalid/unused, or the prefix of default * routes. These functions should be used in the second case, where both IPv4 @@ -207,11 +175,6 @@ static inline int ipa_zero2(ip_addr a) static inline int ipa_nonzero2(ip_addr a) { return _I0(a) || _I1(a) || ((_I2(a) != 0) && (_I2(a) != 0xffff)) || _I3(a); } -#else -#define ipa_zero2(x) ip4_zero(x) -#define ipa_nonzero2(x) ip4_nonzero(x) -#endif - /* * Hash and compare functions @@ -254,16 +217,9 @@ static inline int ip4_compare(ip4_addr a, ip4_addr b) int ip6_compare(ip6_addr a, ip6_addr b); - -#ifdef IPV6 #define ipa_hash(x) ip6_hash(x) #define ipa_hash32(x) ip6_hash32(x) #define ipa_compare(x,y) ip6_compare(x,y) -#else -#define ipa_hash(x) ip4_hash(x) -#define ipa_hash32(x) ip4_hash32(x) -#define ipa_compare(x,y) ip4_compare(x,y) -#endif /* @@ -294,14 +250,10 @@ static inline int ip6_is_link_local(ip6_addr a) static inline int ip6_is_v4mapped(ip6_addr a) { return _I0(a) == 0 && _I1(a) == 0 && _I2(a) == 0xffff; } -#ifdef IPV6 #define ipa_classify(x) ip6_classify(&(x)) #define ipa_is_link_local(x) ip6_is_link_local(x) -#else -#define ipa_classify(x) ip4_classify(x) -#define ipa_is_link_local(x) 0 -#endif +/* XXXX remove */ static inline int ipa_classify_net(ip_addr a) { return ipa_zero2(a) ? (IADDR_HOST | SCOPE_UNIVERSE) : ipa_classify(a); } @@ -365,25 +317,8 @@ static inline ip6_addr ip6_opposite_m2(ip6_addr a) ip4_addr ip4_class_mask(ip4_addr ad); -#ifdef IPV6 -#define ipa_mkmask(x) ip6_mkmask(x) -#define ipa_masklen(x) ip6_masklen(&x) -#define ipa_pxlen(x,y) ip6_pxlen(x,y) -#define ipa_getbit(x,n) ip6_getbit(x,n) -#define ipa_setbit(x,n) ip6_setbit(x,n) -#define ipa_clrbit(x,n) ip6_clrbit(x,n) #define ipa_opposite_m1(x) ip6_opposite_m1(x) #define ipa_opposite_m2(x) ip6_opposite_m2(x) -#else -#define ipa_mkmask(x) ip4_mkmask(x) -#define ipa_masklen(x) ip4_masklen(x) -#define ipa_pxlen(x,y) ip4_pxlen(x,y) -#define ipa_getbit(x,n) ip4_getbit(x,n) -#define ipa_setbit(x,n) ip4_setbit(x,n) -#define ipa_clrbit(x,n) ip4_clrbit(x,n) -#define ipa_opposite_m1(x) ip4_opposite_m1(x) -#define ipa_opposite_m2(x) ip4_opposite_m2(x) -#endif /* @@ -402,14 +337,6 @@ static inline ip6_addr ip6_hton(ip6_addr a) static inline ip6_addr ip6_ntoh(ip6_addr a) { return _MI6(ntohl(_I0(a)), ntohl(_I1(a)), ntohl(_I2(a)), ntohl(_I3(a))); } -#ifdef IPV6 -#define ipa_hton(x) x = ip6_hton(x) -#define ipa_ntoh(x) x = ip6_ntoh(x) -#else -#define ipa_hton(x) x = ip4_hton(x) -#define ipa_ntoh(x) x = ip4_ntoh(x) -#endif - /* * Unaligned data access (in network order) @@ -440,15 +367,6 @@ static inline void * put_ip6(void *buf, ip6_addr a) return buf+16; } -// XXXX these functions must be redesigned or removed -#ifdef IPV6 -#define get_ipa(x) get_ip6(x) -#define put_ipa(x,y) put_ip6(x,y) -#else -#define get_ipa(x) get_ip4(x) -#define put_ipa(x,y) put_ip4(x,y) -#endif - /* * Binary/text form conversions @@ -466,28 +384,11 @@ static inline char * ip6_ntox(ip6_addr a, char *b) int ip4_pton(const char *a, ip4_addr *o); int ip6_pton(const char *a, ip6_addr *o); -// XXXX these functions must be redesigned or removed -#ifdef IPV6 -#define ipa_ntop(x,y) ip6_ntop(x,y) -#define ipa_ntox(x,y) ip6_ntox(x,y) -#define ipa_pton(x,y) ip6_pton(x,y) -#else -#define ipa_ntop(x,y) ip4_ntop(x,y) -#define ipa_ntox(x,y) ip4_ntox(x,y) -#define ipa_pton(x,y) ip4_pton(x,y) -#endif - /* * Miscellaneous */ -// XXXX review this - -#define ip_is_prefix(a,l) (!ipa_nonzero(ipa_and(a, ipa_not(ipa_mkmask(l))))) -#define ipa_in_net(x,n,p) (ipa_zero(ipa_and(ipa_xor((n),(x)),ipa_mkmask(p)))) -#define net_in_net(n1,l1,n2,l2) (((l1) >= (l2)) && (ipa_zero(ipa_and(ipa_xor((n1),(n2)),ipa_mkmask(l2))))) - char *ip_scope_text(uint); #endif diff --git a/lib/net.c b/lib/net.c index 09f23c7a..76ecd460 100644 --- a/lib/net.c +++ b/lib/net.c @@ -136,33 +136,36 @@ net_classify(const net_addr *N) return ip6_zero(n->ip6.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip6_classify(&n->ip6.prefix); } - return 0; + return IADDR_INVALID; } int -ipa_in_netX(const ip_addr A, const net_addr *N) +ipa_in_netX(const ip_addr a, const net_addr *n) { - switch (N->type) + switch (n->type) { case NET_IP4: case NET_VPN4: - if (!ipa_is_ip4(A)) return 0; - break; + if (!ipa_is_ip4(a)) return 0; + return ip4_zero(ip4_and(ip4_xor(ipa_to_ip4(a), net4_prefix(n)), + ip4_mkmask(net4_pxlen(n)))); case NET_IP6: case NET_VPN6: - if (ipa_is_ip4(A)) return 0; - break; - } + if (ipa_is_ip4(a)) return 0; + return ip6_zero(ip6_and(ip6_xor(ipa_to_ip6(a), net6_prefix(n)), + ip6_mkmask(net6_pxlen(n)))); - return ipa_zero(ipa_and(ipa_xor(A, net_prefix(N)), ipa_mkmask(net_pxlen(N)))); + default: + return 0; + } } int -net_in_netX(const net_addr *A, const net_addr *N) +net_in_netX(const net_addr *a, const net_addr *n) { - if (A->type != N->type) + if (a->type != n->type) return 0; - return (net_pxlen(N) <= net_pxlen(A)) && ipa_in_netX(net_prefix(A), N); + return (net_pxlen(n) <= net_pxlen(a)) && ipa_in_netX(net_prefix(a), n); } diff --git a/nest/config.Y b/nest/config.Y index de75509f..9d20dd48 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -55,7 +55,7 @@ CF_DECLS CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT) CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS) -CF_KEYWORDS(IPV4, IPVX, VPN4, VPN6) +CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6) CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED) CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES) CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, NOEXPORT, GENERATE) /* ,ROA */ @@ -134,7 +134,7 @@ CF_ADDTO(conf, table) table_type: /* empty */ { $$ = NET_IP4; } | IPV4 { $$ = NET_IP4; } - | IPVX { $$ = NET_IP6; } /* XXXX */ + | IPV6 { $$ = NET_IP6; } | VPN4 { $$ = NET_VPN4; } | VPN6 { $$ = NET_VPN6; } ; diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y index 6d8fa755..5673ef60 100644 --- a/proto/ospf/config.Y +++ b/proto/ospf/config.Y @@ -316,7 +316,6 @@ ospf_iface_item: | TTL SECURITY bool { OSPF_PATT->ttl_security = $3; } | TTL SECURITY TX ONLY { OSPF_PATT->ttl_security = 2; } | BFD bool { OSPF_PATT->bfd = $2; cf_check_bfd($2); } - | SECONDARY bool { OSPF_PATT->bsd_secondary = $2; } | password_list { ospf_check_auth(); } ; diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c index 91e22266..442cec3a 100644 --- a/proto/ospf/iface.c +++ b/proto/ospf/iface.c @@ -525,15 +525,6 @@ ospf_iface_stubby(struct ospf_iface_patt *ip, struct ifa *addr) if (addr->iface->flags & IF_LOOPBACK) return 1; - /* - * For compatibility reasons on BSD systems, we force OSPF - * interfaces with non-primary IP prefixes to be stub. - */ -#if defined(OSPFv2) && !defined(CONFIG_MC_PROPER_SRC) - if (!ip->bsd_secondary && !(addr->flags & IA_PRIMARY)) - return 1; -#endif - return ip->stub; } diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index f4f91de1..b1e02b24 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -185,7 +185,6 @@ struct ospf_iface_patt u8 ptp_netmask; /* bool + 2 for unspecified */ u8 ttl_security; /* bool + 2 for TX only */ u8 bfd; - u8 bsd_secondary; list *passwords; }; diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c index 19e82047..dd62b375 100644 --- a/sysdep/bsd/krt-sock.c +++ b/sysdep/bsd/krt-sock.c @@ -71,6 +71,7 @@ #define KRT_MAX_TABLES 1 #endif +#define IPV6 1 /* Dynamic max number of tables */ diff --git a/sysdep/config.h b/sysdep/config.h index 9620a37d..08c15fe9 100644 --- a/sysdep/config.h +++ b/sysdep/config.h @@ -9,9 +9,6 @@ /* BIRD version */ #define BIRD_VERSION "1.5.0" -/* XXXX Temporary */ -#define IPV6 1 - /* Include parameters determined by configure script */ #include "sysdep/autoconf.h" diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c index b3d0a9ab..201d074e 100644 --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@ -1169,7 +1169,8 @@ nl_parse_route(struct nlmsghdr *h, int scan) 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)) + const net_addr_ip6 sit = NET_ADDR_IP6(IP6_NONE, 96); + if ((i->rtm_family == AF_INET6) && ipa_in_netX(ra.gw, (net_addr *) &sit)) return; neighbor *nbr; diff --git a/sysdep/unix/krt.Y b/sysdep/unix/krt.Y index e769ec0f..eb0ae109 100644 --- a/sysdep/unix/krt.Y +++ b/sysdep/unix/krt.Y @@ -69,8 +69,7 @@ kif_item: } | PRIMARY opttext net_or_ipa { struct kif_primary_item *kpi = cfg_alloc(sizeof (struct kif_primary_item)); - kpi->prefix = IPA_NONE; /* XXXX */ - kpi->pxlen = 0; /* XXXX */ + kpi->addr = $3.n; add_tail(&THIS_KIF->primary, &kpi->n); } ; diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index 73324f38..41293a06 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -131,14 +131,14 @@ prefer_addr(struct ifa *a, struct ifa *b) } static inline struct ifa * -find_preferred_ifa(struct iface *i, ip_addr prefix, ip_addr mask) +find_preferred_ifa(struct iface *i, const net_addr *n) { struct ifa *a, *b = NULL; WALK_LIST(a, i->addrs) { if (!(a->flags & IA_SECONDARY) && - ipa_equal(ipa_and(a->ip, mask), prefix) && + (!n || ipa_in_netX(a->ip, n)) && (!b || prefer_addr(a, b))) b = a; } @@ -156,14 +156,14 @@ kif_choose_primary(struct iface *i) WALK_LIST(it, cf->primary) { if (!it->pattern || patmatch(it->pattern, i->name)) - if (a = find_preferred_ifa(i, it->prefix, ipa_mkmask(it->pxlen))) + if (a = find_preferred_ifa(i, &it->addr)) return a; } if (a = kif_get_primary_ip(i)) return a; - return find_preferred_ifa(i, IPA_NONE, IPA_NONE); + return find_preferred_ifa(i, NULL); } diff --git a/sysdep/unix/krt.h b/sysdep/unix/krt.h index 4b66ea83..f05dc37e 100644 --- a/sysdep/unix/krt.h +++ b/sysdep/unix/krt.h @@ -97,8 +97,7 @@ extern struct protocol proto_unix_iface; struct kif_primary_item { node n; byte *pattern; - ip_addr prefix; - int pxlen; + net_addr addr; }; struct kif_config { diff --git a/sysdep/unix/unix.h b/sysdep/unix/unix.h index 58ceab1e..6e788f08 100644 --- a/sysdep/unix/unix.h +++ b/sysdep/unix/unix.h @@ -80,14 +80,8 @@ static inline ip_addr ipa_from_sa(sockaddr *sa) static inline struct in_addr ipa_to_in4(ip_addr a) { return (struct in_addr) { htonl(ipa_to_u32(a)) }; } -#ifdef IPV6 static inline struct in6_addr ipa_to_in6(ip_addr a) { return (struct in6_addr) { .s6_addr32 = { htonl(_I0(a)), htonl(_I1(a)), htonl(_I2(a)), htonl(_I3(a)) } }; } -#else -/* Temporary dummy */ -static inline struct in6_addr ipa_to_in6(ip_addr a) -{ return (struct in6_addr) { .s6_addr32 = { 0, 0, 0, 0 } }; } -#endif void sockaddr_fill(sockaddr *sa, int af, ip_addr a, struct iface *ifa, uint port); int sockaddr_read(sockaddr *sa, int af, ip_addr *a, struct iface **ifa, uint *port);