diff options
Diffstat (limited to 'sysdep')
-rw-r--r-- | sysdep/bsd/krt-sock.c | 47 | ||||
-rw-r--r-- | sysdep/linux/netlink.c | 38 | ||||
-rw-r--r-- | sysdep/unix/io.c | 16 | ||||
-rw-r--r-- | sysdep/unix/unix.h | 18 |
4 files changed, 75 insertions, 44 deletions
diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c index 1db39493..19e82047 100644 --- a/sysdep/bsd/krt-sock.c +++ b/sysdep/bsd/krt-sock.c @@ -207,7 +207,8 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e) msg.rtm.rtm_addrs = RTA_DST; msg.rtm.rtm_flags = RTF_UP | RTF_PROTO1; - if (net_prefix(net->n.addr) == MAX_PREFIX_LENGTH) + /* XXXX */ + if (net_pxlen(net->n.addr) == net_max_prefix_length[net->n.addr->type]) msg.rtm.rtm_flags |= RTF_HOST; else msg.rtm.rtm_addrs |= RTA_NETMASK; @@ -296,7 +297,7 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e) return -1; } - sockaddr_fill(&gate, BIRD_AF, i->addr->ip, NULL, 0); + sockaddr_fill(&gate, ipa_is_ip4(i->addr->ip) ? AF_INET : AF_INET6, i->addr->ip, NULL, 0); msg.rtm.rtm_addrs |= RTA_GATEWAY; } break; @@ -383,12 +384,17 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan) GETADDR(&gate, RTA_GATEWAY); GETADDR(&mask, RTA_NETMASK); - if (dst.sa.sa_family != BIRD_AF) - SKIP("invalid DST"); + + switch (dst.sa.sa_family) { + case AF_INET: + case AF_INET6: break; + default: + SKIP("invalid DST"); + } idst = ipa_from_sa(&dst); - imask = ipa_from_sa(&mask); - igate = (gate.sa.sa_family == BIRD_AF) ? ipa_from_sa(&gate) : IPA_NONE; + imask = ipa_from_sa(&mask); /* XXXX broken, see below */ + igate = (gate.sa.sa_family == dst.sa.sa_family) ? ipa_from_sa(&gate) : IPA_NONE; /* We do not test family for RTA_NETMASK, because BSD sends us some strange values, but interpreting them as IPv4/IPv6 works */ @@ -398,7 +404,7 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan) if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK)) SKIP("strange class/scope\n"); - int pxlen = (flags & RTF_HOST) ? MAX_PREFIX_LENGTH : ipa_masklen(imask); + int pxlen = (flags & RTF_HOST) ? (ipa_is_ip4(imask) ? IP4_MAX_PREFIX_LENGTH : IP6_MAX_PREFIX_LENGTH) : ipa_masklen(imask); if (pxlen < 0) { log(L_ERR "%s (%I) - netmask %I", errmsg, idst, imask); return; } @@ -663,9 +669,13 @@ krt_read_addr(struct ks_msg *msg, int scan) GETADDR (&null, RTA_AUTHOR); GETADDR (&brd, RTA_BRD); - /* Some other family address */ - if (addr.sa.sa_family != BIRD_AF) - return; + /* Is addr family IP4 or IP6? */ + int ipv6; + switch (addr.sa.sa_family) { + case AF_INET: ipv6 = 0; break; + case AF_INET6: ipv6 = 1; break; + default: return; + } iaddr = ipa_from_sa(&addr); imask = ipa_from_sa(&mask); @@ -701,16 +711,16 @@ krt_read_addr(struct ks_msg *msg, int scan) } ifa.scope = scope & IADDR_SCOPE_MASK; - if (masklen < BITS_PER_IP_ADDRESS) + if (masklen < (ipv6 ? IP6_MAX_PREFIX_LENGTH : IP4_MAX_PREFIX_LENGTH)) { net_fill_ipa(&ifa.prefix, ifa.ip, masklen); net_normalize(&ifa.prefix); - if (masklen == (BITS_PER_IP_ADDRESS - 1)) + if (masklen == ((ipv6 ? IP6_MAX_PREFIX_LENGTH : IP4_MAX_PREFIX_LENGTH) - 1)) ifa.opposite = ipa_opposite_m1(ifa.ip); #ifndef IPV6 - if (masklen == (BITS_PER_IP_ADDRESS - 2)) + if (!ipv6 && masklen == IP4_MAX_PREFIX_LENGTH - 2) ifa.opposite = ipa_opposite_m2(ifa.ip); #endif @@ -722,13 +732,13 @@ krt_read_addr(struct ks_msg *msg, int scan) } else if (!(iface->flags & IF_MULTIACCESS) && ipa_nonzero(ibrd)) { - net_fill_ipa(&ifa.prefix, ibrd, BITS_PER_IP_ADDRESS); + net_fill_ipa(&ifa.prefix, ibrd, (ipv6 ? IP6_MAX_PREFIX_LENGTH : IP4_MAX_PREFIX_LENGTH)); ifa.opposite = ibrd; ifa.flags |= IA_PEER; } else { - net_fill_ipa(&ifa.prefix, ifa.ip, BITS_PER_IP_ADDRESS); + net_fill_ipa(&ifa.prefix, ifa.ip, (ipv6 ? IP6_MAX_PREFIX_LENGTH : IP4_MAX_PREFIX_LENGTH)); ifa.flags |= IA_HOST; } @@ -825,7 +835,12 @@ krt_sysctl_scan(struct proto *p, int cmd, int table_id) mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; - mib[3] = BIRD_AF; + /* XXX: This value should be given from the caller */ +#ifdef IPV6 + mib[3] = AF_INET6; +#else + mib[3] = AF_INET; +#endif mib[4] = cmd; mib[5] = 0; mcnt = 6; diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c index 7c4c4b2b..d5c8a2ab 100644 --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@ -646,12 +646,12 @@ nl_parse_addr4(struct ifaddrmsg *i, int scan, int new) ifa.ip = rta_get_ipa(a[IFA_LOCAL]); - if (i->ifa_prefixlen > BITS_PER_IP_ADDRESS) + if (i->ifa_prefixlen > IP4_MAX_PREFIX_LENGTH) { log(L_ERR "KIF: Invalid prefix length for interface %s: %d", ifi->name, i->ifa_prefixlen); new = 0; } - if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS) + if (i->ifa_prefixlen == IP4_MAX_PREFIX_LENGTH) { ifa.brd = rta_get_ipa(a[IFA_ADDRESS]); net_fill_ip4(&ifa.prefix, rta_get_ip4(a[IFA_ADDRESS]), i->ifa_prefixlen); @@ -670,10 +670,10 @@ nl_parse_addr4(struct ifaddrmsg *i, int scan, int new) net_fill_ip4(&ifa.prefix, ipa_to_ip4(ifa.ip), i->ifa_prefixlen); net_normalize(&ifa.prefix); - if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS - 1) + if (i->ifa_prefixlen == IP4_MAX_PREFIX_LENGTH - 1) ifa.opposite = ipa_opposite_m1(ifa.ip); - if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS - 2) + if (i->ifa_prefixlen == IP4_MAX_PREFIX_LENGTH - 2) ifa.opposite = ipa_opposite_m2(ifa.ip); if ((ifi->flags & IF_BROADCAST) && a[IFA_BROADCAST]) @@ -746,12 +746,12 @@ nl_parse_addr6(struct ifaddrmsg *i, int scan, int new) ifa.ip = rta_get_ipa(a[IFA_LOCAL] ? : a[IFA_ADDRESS]); - if (i->ifa_prefixlen > BITS_PER_IP_ADDRESS) + if (i->ifa_prefixlen > IP6_MAX_PREFIX_LENGTH) { log(L_ERR "KIF: Invalid prefix length for interface %s: %d", ifi->name, i->ifa_prefixlen); new = 0; } - if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS) + if (i->ifa_prefixlen == IP6_MAX_PREFIX_LENGTH) { ifa.brd = rta_get_ipa(a[IFA_ADDRESS]); net_fill_ip6(&ifa.prefix, rta_get_ip6(a[IFA_ADDRESS]), i->ifa_prefixlen); @@ -770,7 +770,7 @@ nl_parse_addr6(struct ifaddrmsg *i, int scan, int new) net_fill_ip6(&ifa.prefix, ipa_to_ip6(ifa.ip), i->ifa_prefixlen); net_normalize(&ifa.prefix); - if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS - 1) + if (i->ifa_prefixlen == IP6_MAX_PREFIX_LENGTH - 1) ifa.opposite = ipa_opposite_m1(ifa.ip); } @@ -831,14 +831,21 @@ kif_do_scan(struct kif_proto *p UNUSED) nl_parse_link(h, 1); else log(L_DEBUG "nl_scan_ifaces: Unknown packet received (type=%d)", h->nlmsg_type); - - nl_request_dump(BIRD_AF, RTM_GETADDR); +#ifndef IPV6 + nl_request_dump(AF_INET, RTM_GETADDR); while (h = nl_get_scan()) if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR) nl_parse_addr(h, 1); else log(L_DEBUG "nl_scan_ifaces: Unknown packet received (type=%d)", h->nlmsg_type); - +#else + nl_request_dump(AF_INET6, RTM_GETADDR); + while (h = nl_get_scan()) + if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR) + nl_parse_addr(h, 1); + else + log(L_DEBUG "nl_scan_ifaces: Unknown packet received (type=%d)", h->nlmsg_type); +#endif if_end_update(); } @@ -1280,12 +1287,21 @@ krt_do_scan(struct krt_proto *p UNUSED) /* CONFIG_ALL_TABLES_AT_ONCE => p is NUL { struct nlmsghdr *h; - nl_request_dump(BIRD_AF, RTM_GETROUTE); +#ifndef IPV6 + nl_request_dump(AF_INET, RTM_GETROUTE); while (h = nl_get_scan()) if (h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE) nl_parse_route(h, 1); else log(L_DEBUG "nl_scan_fire: Unknown packet received (type=%d)", h->nlmsg_type); +#else + nl_request_dump(AF_INET6, RTM_GETROUTE); + while (h = nl_get_scan()) + if (h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE) + nl_parse_route(h, 1); + else + log(L_DEBUG "nl_scan_fire: Unknown packet received (type=%d)", h->nlmsg_type); +#endif } /* diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index b636e799..bc00def9 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -1311,8 +1311,8 @@ sk_passive_connected(sock *s, int type) sock *t = sk_new(s->pool); t->type = type; - t->fd = fd; t->af = s->af; + t->fd = fd; t->ttl = s->ttl; t->tos = s->tos; t->rbsize = s->rbsize; @@ -1371,7 +1371,6 @@ sk_passive_connected(sock *s, int type) int sk_open(sock *s) { - int af = BIRD_AF; int fd = -1; int do_bind = 0; int bind_port = 0; @@ -1384,28 +1383,28 @@ sk_open(sock *s) s->ttx = ""; /* Force s->ttx != s->tpos */ /* Fall thru */ case SK_TCP_PASSIVE: - fd = socket(af, SOCK_STREAM, IPPROTO_TCP); + fd = socket(s->af, SOCK_STREAM, IPPROTO_TCP); bind_port = s->sport; bind_addr = s->saddr; do_bind = bind_port || ipa_nonzero(bind_addr); break; case SK_UDP: - fd = socket(af, SOCK_DGRAM, IPPROTO_UDP); + fd = socket(s->af, SOCK_DGRAM, IPPROTO_UDP); bind_port = s->sport; bind_addr = (s->flags & SKF_BIND) ? s->saddr : IPA_NONE; do_bind = 1; break; case SK_IP: - fd = socket(af, SOCK_RAW, s->dport); + fd = socket(s->af, SOCK_RAW, s->dport); bind_port = 0; bind_addr = (s->flags & SKF_BIND) ? s->saddr : IPA_NONE; do_bind = ipa_nonzero(bind_addr); break; case SK_MAGIC: - af = 0; + s->af = 0; fd = s->fd; break; @@ -1419,7 +1418,6 @@ sk_open(sock *s) if (fd >= FD_SETSIZE) ERR2("FD_SETSIZE limit reached"); - s->af = af; s->fd = fd; if (sk_setup(s) < 0) @@ -1448,7 +1446,7 @@ sk_open(sock *s) if (sk_set_high_port(s) < 0) log(L_WARN "Socket error: %s%#m", s->err); - sockaddr_fill(&sa, af, bind_addr, s->iface, bind_port); + sockaddr_fill(&sa, s->af, bind_addr, s->iface, bind_port); if (bind(fd, &sa.sa, SA_LEN(sa)) < 0) ERR2("bind"); } @@ -1460,7 +1458,7 @@ sk_open(sock *s) switch (s->type) { case SK_TCP_ACTIVE: - sockaddr_fill(&sa, af, s->daddr, s->iface, s->dport); + sockaddr_fill(&sa, s->af, s->daddr, s->iface, s->dport); if (connect(fd, &sa.sa, SA_LEN(sa)) >= 0) sk_tcp_connected(s); else if (errno != EINTR && errno != EAGAIN && errno != EINPROGRESS && diff --git a/sysdep/unix/unix.h b/sysdep/unix/unix.h index 4e0ff841..58ceab1e 100644 --- a/sysdep/unix/unix.h +++ b/sysdep/unix/unix.h @@ -47,14 +47,6 @@ typedef struct sockaddr_bird { } sockaddr; -#ifdef IPV6 -#define BIRD_AF AF_INET6 -#define ipa_from_sa(x) ipa_from_sa6(x) -#else -#define BIRD_AF AF_INET -#define ipa_from_sa(x) ipa_from_sa4(x) -#endif - /* This is sloppy hack, it should be detected by configure script */ /* Linux systems have it defined so this is definition for BSD systems */ @@ -75,6 +67,16 @@ static inline ip_addr ipa_from_sa4(sockaddr *sa) static inline ip_addr ipa_from_sa6(sockaddr *sa) { return ipa_from_in6(((struct sockaddr_in6 *) sa)->sin6_addr); } +static inline ip_addr ipa_from_sa(sockaddr *sa) +{ + switch (sa->sa.sa_family) + { + case AF_INET: return ipa_from_sa4(sa); + case AF_INET6: return ipa_from_sa6(sa); + default: return IPA_NONE; + } +} + static inline struct in_addr ipa_to_in4(ip_addr a) { return (struct in_addr) { htonl(ipa_to_u32(a)) }; } |