]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Adapts BSD sysdep code for integrated branch.
authorOndrej Zajicek <santiago@crfreenet.org>
Thu, 27 Jun 2013 22:57:22 +0000 (00:57 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Thu, 27 Jun 2013 22:57:22 +0000 (00:57 +0200)
Thanks to Alexander V. Chernikov for the original patch.

lib/socket.h
nest/rt-table.c
sysdep/bsd/krt-sock.c
sysdep/bsd/krt-sys.h
sysdep/bsd/sysio.h
sysdep/linux/sysio.h
sysdep/unix/io.c
sysdep/unix/krt.c
sysdep/unix/unix.h

index cbef4fdc000d8183318ac6c421656d2c9d7ac605..353e9573e21231c3b229beb1a0b612589fdbbd6c 100644 (file)
@@ -10,6 +10,7 @@
 #define _BIRD_SOCKET_H_
 
 #include <errno.h>
+#include <sys/socket.h>
 
 #include "lib/resource.h"
 
index c93950c4f34738bf9e9a977271a86da8ada23869..1cb25ab394a5ba08a9ae9e8cabe63ef58a264f2e 100644 (file)
@@ -1231,9 +1231,9 @@ rt_addrsize(int addr_type)
   switch (addr_type)
   {
 #ifdef MPLS_VPN
-    case RT_VPNV4:
+    case RT_VPN4:
       return sizeof(vpn4_addr);
-    case RT_VPNV6:
+    case RT_VPN6:
       return sizeof(vpn6_addr);
 #endif
     case RT_IPV4:
index 1b09984f3a974aee5df30059cb247b32e64977db..6aabef2b0a512da5781578b64673c5ed040951d3 100644 (file)
@@ -65,6 +65,20 @@ krt_capable(rte *e)
      );
 }
 
+static int
+rt_to_af(int rt)
+{
+  if (rt == RT_IPV4)
+    return AF_INET;
+  else if (rt == RT_IPV6)
+    return AF_INET6;
+
+  /* RT_IP (0) maps to 0 (every AF) */
+
+  return 0;
+}
+
+
 #define ROUNDUP(a) \
         ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
 
@@ -87,10 +101,10 @@ krt_sock_send(int cmd, rte *e)
   rta *a = e->attrs;
   static int msg_seq;
   struct iface *j, *i = a->iface;
-  int l;
+  int af = 0, l;
   struct ks_msg msg;
   char *body = (char *)msg.buf;
-  sockaddr gate, mask, dst;
+  struct sockaddr_in6 gate, mask, dst;
   ip_addr gw;
 
   DBG("krt-sock: send %F via %I\n", &net->n, a->gw);
@@ -131,29 +145,43 @@ krt_sock_send(int cmd, rte *e)
 
   gw = a->gw;
 
-#ifdef IPV6
-  /* Embed interface ID to link-local address */
-  if (ipa_has_link_scope(gw))
-    _I0(gw) = 0xfe800000 | (i->index & 0x0000ffff);
-#endif
+  switch (net->n.addr_type)
+  {
+    case RT_IPV4:
+      af = AF_INET;
+      dst.sin6_family = mask.sin6_family = gate.sin6_family = af;
+      sockaddr_fill((struct sockaddr *)&dst, *FPREFIX_IP(&net->n), NULL, 0);
+      sockaddr_fill((struct sockaddr *)&mask, ipa_mkmask(net->n.pxlen), NULL, 0);
+      sockaddr_fill((struct sockaddr *)&gate, gw, NULL, 0);
+
+      if (net->n.pxlen == MAX_PREFIX_LENGTH)
+       msg.rtm.rtm_flags |= RTF_HOST;
+      else
+       msg.rtm.rtm_addrs |= RTA_NETMASK;
+      break;
+
+    case RT_IPV6:
+      af = AF_INET6;
 
-  fill_in_sockaddr(&dst, net->n.prefix, NULL, 0);
-  fill_in_sockaddr(&mask, ipa_mkmask(net->n.pxlen), NULL, 0);
-  fill_in_sockaddr(&gate, gw, NULL, 0);
-  /* XXXX from patch
-  if (net->n.addr_type == RT_IP)
-   {
-     fill_in_sockaddr(&dst, *FPREFIX_IP(&net->n), 0);
-     fill_in_sockaddr(&mask, ipa_mkmask(net->n.pxlen), 0);
-
-     if (net->n.pxlen == MAX_PREFIX_LENGTH)
-       msg.rtm.rtm_flags |= RTF_HOST;
-     else
-       msg.rtm.rtm_addrs |= RTA_NETMASK;
-   }
-  */
+      /* Embed interface ID to link-local address */
+      if (ipa_is_link_local(gw))
+       _I0(gw) = 0xfe800000 | (i->index & 0x0000ffff);
+
+      dst.sin6_family = mask.sin6_family = gate.sin6_family = af;
+      sockaddr_fill((struct sockaddr *)&dst, *FPREFIX_IP(&net->n), NULL, 0);
+      sockaddr_fill((struct sockaddr *)&mask, ipa_mkmask(net->n.pxlen), NULL, 0);
+      sockaddr_fill((struct sockaddr *)&gate, gw, NULL, 0);
+
+      if (net->n.pxlen == MAX_PREFIX_LENGTH)
+       msg.rtm.rtm_flags |= RTF_HOST;
+      else
+       msg.rtm.rtm_addrs |= RTA_NETMASK;
+      break;
+
+    default:
+      log(L_ERR "Unsupported address family: %F", FPREFIX_IP(&net->n));
+      return -1;
+  }
 
   switch (a->dest)
   {
@@ -175,12 +203,13 @@ krt_sock_send(int cmd, rte *e)
           msg.rtm.rtm_flags |= RTF_CLONING;
 #endif
 
+       // XXXX: find proper IPv4 / IPv6 address ?
         if(!i->addr) {
-          log(L_ERR "KRT: interface %s has no IP addess", i->name);
+          log(L_ERR "KRT: interface %s has no IP address", i->name);
           return -1;
         }
 
-        fill_in_sockaddr(&gate, i->addr->ip, NULL, 0);
+       sockaddr_fill((struct sockaddr *)&gate, i->addr->ip, NULL, 0);
         msg.rtm.rtm_addrs |= RTA_GATEWAY;
       }
       break;
@@ -230,15 +259,15 @@ krt_read_rt(struct ks_msg *msg, struct krt_proto *p, int scan)
 {
   rte *e;
   net *net;
-  sockaddr dst, gate, mask;
+  struct sockaddr_in6 dst, gate, mask;
   ip_addr idst, igate, imask;
   void *body = (char *)msg->buf;
   int new = (msg->rtm.rtm_type == RTM_ADD);
-  char *errmsg = "KRT: Invalid route received";
   int flags = msg->rtm.rtm_flags;
   int addrs = msg->rtm.rtm_addrs;
-  int src;
+  int af, pxlen, src;
   byte src2;
+  char *errmsg = "KRT: Invalid route received";
 
   if (!(flags & RTF_UP) && scan)
     SKIP("not up in scan\n");
@@ -253,26 +282,52 @@ krt_read_rt(struct ks_msg *msg, struct krt_proto *p, int scan)
   GETADDR(&gate, RTA_GATEWAY);
   GETADDR(&mask, RTA_NETMASK);
 
-  if (sa_family_check(&dst))
-    get_sockaddr(&dst, &idst, NULL, NULL, 0);
-  else
-    SKIP("invalid DST");
+  af = dst.sin6_family;
+
+  /* XXX: AF_MPLS */
+
+  switch (af)
+  {
+    case AF_INET:
+      /* Silently discard */
+      if (p->addr_type != RT_IPV4)
+       return;
+      break;
+
+    case AF_INET6:
+      /* Silently discard */
+      if (p->addr_type != RT_IPV6)
+       return;
+      break;
+
+    default:
+      SKIP("Invalid DST");
+  }
+
+  sockaddr_read((struct sockaddr *)&dst, &idst, NULL, NULL, 1);
 
   /* We will check later whether we have valid gateway addr */
-  if (sa_family_check(&gate))
-    get_sockaddr(&gate, &igate, NULL, NULL, 0);
+  if (gate.sin6_family == af)
+    sockaddr_read((struct sockaddr *)&gate, &igate, NULL, NULL, 0);
   else
     igate = IPA_NONE;
 
   /* We do not test family for RTA_NETMASK, because BSD sends us
      some strange values, but interpreting them as IPv4/IPv6 works */
-  get_sockaddr(&mask, &imask, NULL, NULL, 0);
+  mask.sin6_family = dst.sin6_family;
+
+  sockaddr_read((struct sockaddr *)&mask, &imask, NULL, NULL, 1);
 
   int c = ipa_classify_net(idst);
   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_mklen(imask);
+  if (af == AF_INET6)
+    pxlen = (flags & RTF_HOST) ? MAX_PREFIX_LENGTH : ip6_masklen(&imask);
+  else
+    pxlen = (flags & RTF_HOST) ? MAX_PREFIX_LENGTH : 
+      (ip4_masklen(ipa_to_ip4(imask)) + 96); // XXXX: Hack
+
   if (pxlen < 0)
     { log(L_ERR "%s (%I) - netmask %I", errmsg, idst, imask); return; }
 
@@ -356,11 +411,12 @@ krt_read_rt(struct ks_msg *msg, struct krt_proto *p, int scan)
     a.dest = RTD_ROUTER;
     a.gw = igate;
 
-#ifdef IPV6
-    /* Clean up embedded interface ID returned in link-local address */
-    if (ipa_has_link_scope(a.gw))
-      _I0(a.gw) = 0xfe800000;
-#endif
+    if (af == AF_INET6)
+      {
+       /* Clean up embedded interface ID returned in link-local address */
+       if (ipa_is_link_local(a.gw))
+         _I0(a.gw) = 0xfe800000;
+      }
 
     ng = neigh_find2(&p->p, &a.gw, a.iface, 0);
     if (!ng || (ng->scope == SCOPE_HOST))
@@ -503,13 +559,13 @@ krt_read_addr(struct ks_msg *msg)
 {
   struct ifa_msghdr *ifam = (struct ifa_msghdr *)&msg->rtm;
   void *body = (void *)(ifam + 1);
-  sockaddr addr, mask, brd;
+  struct sockaddr_in6 addr, mask, brd;
   struct iface *iface = NULL;
   struct ifa ifa;
   struct sockaddr null;
   ip_addr iaddr, imask, ibrd;
   int addrs = ifam->ifam_addrs;
-  int scope, masklen = -1;
+  int ipv4, scope, masklen = -1, maxlen;
   int new = (ifam->ifam_type == RTM_NEWADDR);
 
   /* Strange messages with zero (invalid) ifindex appear on OpenBSD */
@@ -531,20 +587,33 @@ krt_read_addr(struct ks_msg *msg)
   GETADDR (&null, RTA_AUTHOR);
   GETADDR (&brd, RTA_BRD);
 
-  /* Some other family address */
-  if (!sa_family_check(&addr))
+  /* Basic family check */
+  if (addr.sin6_family != AF_INET && addr.sin6_family != AF_INET6)
     return;
 
-  get_sockaddr(&addr, &iaddr, NULL, NULL, 0);
-  get_sockaddr(&mask, &imask, NULL, NULL, 0);
-  get_sockaddr(&brd, &ibrd, NULL, NULL, 0);
+  ipv4 = (addr.sin6_family == AF_INET) ? 1 : 0;
 
-  if ((masklen = ipa_mklen(imask)) < 0)
+  /*
+   * Work around (Free?)BSD bug with netmask
+   * family not being filled in IPv6 case.
+   * FreeBSD fix: r250815.
+   */
+  if (addr.sin6_family == AF_INET6 && mask.sin6_family == 0)
+         mask.sin6_family = AF_INET6;
+
+  sockaddr_read((struct sockaddr *)&addr, &iaddr, NULL, NULL, 0);
+  sockaddr_read((struct sockaddr *)&mask, &imask, NULL, NULL, 0);
+  sockaddr_read((struct sockaddr *)&brd, &ibrd, NULL, NULL, 0);
+
+  masklen = ipv4 ? (ip4_masklen(ipa_to_ip4(imask)) + 96) : ip6_masklen(&imask);  // XXXX: Hack
+  if (masklen < 0)
   {
     log("Invalid masklen");
     return;
   }
 
+  // log("got %I/%I (%d)", iaddr, imask, masklen);
+
   bzero(&ifa, sizeof(ifa));
 
   ifa.iface = iface;
@@ -561,31 +630,25 @@ krt_read_addr(struct ks_msg *msg)
   }
   ifa.scope = scope & IADDR_SCOPE_MASK;
 
-#ifdef IPV6
   /* Clean up embedded interface ID returned in link-local address */
-  if (ipa_has_link_scope(ifa.ip))
+  if (scope & SCOPE_LINK)
     _I0(ifa.ip) = 0xfe800000;
-#endif
 
-#ifdef IPV6
-  /* Why not the same check also for IPv4? */
-  if ((iface->flags & IF_MULTIACCESS) || (masklen != BITS_PER_IP_ADDRESS))
-#else
-  if (iface->flags & IF_MULTIACCESS)
-#endif
+  // maxlen = ipv4 ? BITS_PER_IP_ADDRESS4 : BITS_PER_IP_ADDRESS6;
+  maxlen = BITS_PER_IP_ADDRESS; // XXXX: Hack
+
+  if ((iface->flags & IF_MULTIACCESS) || (masklen != maxlen))
   {
     ifa.prefix = ipa_and(ifa.ip, ipa_mkmask(masklen));
 
-    if (masklen == BITS_PER_IP_ADDRESS)
+    if (masklen == maxlen)
       ifa.flags |= IA_HOST;
 
-    if (masklen == (BITS_PER_IP_ADDRESS - 1))
+    if (masklen == (maxlen - 1))
       ifa.opposite = ipa_opposite_m1(ifa.ip);
 
-#ifndef IPV6
-    if (masklen == (BITS_PER_IP_ADDRESS - 2))
+    if (ipv4 && masklen == (maxlen - 2))
       ifa.opposite = ipa_opposite_m2(ifa.ip);
-#endif
   }
   else         /* PtP iface */
   {
@@ -627,7 +690,7 @@ krt_read_msg(struct proto *p, struct ks_msg *msg, int scan)
 }
 
 static void
-krt_sysctl_scan(struct proto *p, pool *pool, byte **buf, size_t *bl, int cmd)
+krt_sysctl_scan(struct proto *p, pool *pool, byte **buf, size_t *bl, int cmd, int af)
 {
   byte *next;
   int mib[6];
@@ -638,7 +701,7 @@ krt_sysctl_scan(struct proto *p, pool *pool, byte **buf, size_t *bl, int cmd)
   mib[0] = CTL_NET;
   mib[1] = PF_ROUTE;
   mib[2] = 0;
-  mib[3] = BIRD_PF;
+  mib[3] = af;
   mib[4] = cmd;
   mib[5] = 0;
 
@@ -686,7 +749,8 @@ static size_t kif_buflen = 4096;
 void
 krt_do_scan(struct krt_proto *p)
 {
-  krt_sysctl_scan((struct proto *)p, p->krt_pool, &krt_buffer, &krt_buflen, NET_RT_DUMP);
+  krt_sysctl_scan((struct proto *)p, p->krt_pool, &krt_buffer, &krt_buflen,
+                 NET_RT_DUMP, rt_to_af(p->addr_type));
 }
 
 void
@@ -694,7 +758,7 @@ kif_do_scan(struct kif_proto *p)
 {
   struct proto *P = (struct proto *)p;
   if_start_update();
-  krt_sysctl_scan(P, P->pool, &kif_buffer, &kif_buflen, NET_RT_IFLIST);
+  krt_sysctl_scan(P, P->pool, &kif_buffer, &kif_buflen, NET_RT_IFLIST, 0);
   if_end_update();
 }
 
@@ -747,6 +811,24 @@ krt_sys_shutdown(struct krt_proto *x UNUSED, int last UNUSED)
   krt_buffer = NULL;
 }
 
+static u32 tables;
+
+void
+krt_sys_preconfig(struct config *c UNUSED)
+{
+  tables = 0;
+}
+
+void
+krt_sys_postconfig(struct krt_config *x)
+{
+  u32 id = x->c.table->addr_type;
+
+  if (tables & (1 << id))
+    cf_error("Multiple kernel protocols defined for AF %d", id);
+  tables |= (1 << id);
+}
+
 
 void
 kif_sys_start(struct kif_proto *p UNUSED)
index 88915dde8b569b14702e45267d93ed5dd9662a88..642f5593a01e0c617a051e908a8eb12155e18f86 100644 (file)
@@ -40,8 +40,6 @@ struct krt_status {
 static inline void krt_sys_init(struct krt_proto *p UNUSED) { }
 static inline int krt_sys_reconfigure(struct krt_proto *p UNUSED, struct krt_config *n UNUSED, struct krt_config *o UNUSED) { return 1; }
 
-static inline void krt_sys_preconfig(struct config *c UNUSED) { }
-static inline void krt_sys_postconfig(struct krt_config *c UNUSED) { }
 static inline void krt_sys_init_config(struct krt_config *c UNUSED) { }
 static inline void krt_sys_copy_config(struct krt_config *d UNUSED, struct krt_config *s UNUSED) { }
 
index 4f91def5c2b4e33a95d0603723b38d0ce0f738a6..607d28ffba6067c14e2ac549c8fa898fd35822cc 100644 (file)
@@ -9,54 +9,22 @@
 #ifdef __DragonFly__
 #define TCP_MD5SIG     TCP_SIGNATURE_ENABLE
 #endif
-#ifdef IPV6
-
-static inline void
-set_inaddr(struct in6_addr * ia, ip_addr a)
-{
-  ipa_hton(a);
-  memcpy(ia, &a, sizeof(a));
-}
-
-static inline void
-get_inaddr(ip_addr *a, struct in6_addr *ia)
-{
-  memcpy(a, ia, sizeof(*a));
-  ipa_ntoh(*a);
-}
 
 static inline char *
-sysio_bind_to_iface(sock *s)
+sk_bind_to_iface(sock *s)
 {
   /* Unfortunately not available */
   return NULL;
 }
 
 
-#else
-
 #include <net/if.h>
 #include <net/if_dl.h>
 
-static inline void
-set_inaddr(struct in_addr * ia, ip_addr a)
-{
-  ipa_hton(a);
-  memcpy(&ia->s_addr, &a, sizeof(a));
-}
-
-static inline void
-get_inaddr(ip_addr *a, struct in_addr *ia)
-{
-  memcpy(a, &ia->s_addr, sizeof(*a));
-  ipa_ntoh(*a);
-}
-
-
 /* BSD Multicast handling for IPv4 */
 
 static inline char *
-sysio_setup_multicast(sock *s)
+sk_setup_multicast4(sock *s)
 {
        struct in_addr m;
        u8 zero = 0;
@@ -69,7 +37,7 @@ sysio_setup_multicast(sock *s)
                return "IP_MULTICAST_TTL";
 
        /* This defines where should we send _outgoing_ multicasts */
-        set_inaddr(&m, s->iface->addr->ip);
+        ipa_put_in4(&m, s->iface->addr->ip);
        if (setsockopt(s->fd, IPPROTO_IP, IP_MULTICAST_IF, &m, sizeof(m)) < 0)
                return "IP_MULTICAST_IF";
 
@@ -78,13 +46,13 @@ sysio_setup_multicast(sock *s)
 
 
 static inline char *
-sysio_join_group(sock *s, ip_addr maddr)
+sk_join_group4(sock *s, ip_addr maddr)
 {
        struct ip_mreq  mreq;
 
        bzero(&mreq, sizeof(mreq));
-       set_inaddr(&mreq.imr_interface, s->iface->addr->ip);
-       set_inaddr(&mreq.imr_multiaddr, maddr);
+       ipa_put_in4(&mreq.imr_interface, s->iface->addr->ip);
+       ipa_put_in4(&mreq.imr_multiaddr, maddr);
 
        /* And this one sets interface for _receiving_ multicasts from */
        if (setsockopt(s->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
@@ -94,13 +62,13 @@ sysio_join_group(sock *s, ip_addr maddr)
 }
 
 static inline char *
-sysio_leave_group(sock *s, ip_addr maddr)
+sk_leave_group4(sock *s, ip_addr maddr)
 {
        struct ip_mreq mreq;
 
        bzero(&mreq, sizeof(mreq));
-       set_inaddr(&mreq.imr_interface, s->iface->addr->ip);
-       set_inaddr(&mreq.imr_multiaddr, maddr);
+       ipa_put_in4(&mreq.imr_interface, s->iface->addr->ip);
+       ipa_put_in4(&mreq.imr_multiaddr, maddr);
 
        /* And this one sets interface for _receiving_ multicasts from */
        if (setsockopt(s->fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
@@ -117,7 +85,7 @@ sysio_leave_group(sock *s, ip_addr maddr)
 #define CMSG_TX_SPACE CMSG_SPACE(sizeof(struct in_addr))
 
 static char *
-sysio_register_cmsgs(sock *s)
+sk_request_pktinfo4(sock *s)
 {
   int ok = 1;
   if (s->flags & SKF_LADDR_RX)
@@ -133,29 +101,18 @@ sysio_register_cmsgs(sock *s)
 }
 
 static void
-sysio_process_rx_cmsgs(sock *s, struct msghdr *msg)
+sk_process_rx_cmsg4(sock *s, struct cmsghdr *cm)
 {
-  struct cmsghdr *cm;
-
-  if (!(s->flags & SKF_LADDR_RX))
-    return;
-
-  s->laddr = IPA_NONE;
-  s->lifindex = 0;
-
-  for (cm = CMSG_FIRSTHDR(msg); cm != NULL; cm = CMSG_NXTHDR(msg, cm))
+  if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_RECVDSTADDR)
     {
-      if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_RECVDSTADDR)
-       {
-         struct in_addr *ra = (struct in_addr *) CMSG_DATA(cm);
-         get_inaddr(&s->laddr, ra);
-       }
+      struct in_addr *ra = (struct in_addr *) CMSG_DATA(cm);
+      s->laddr = ipa_get_in4(ra);
+    }
 
-      if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_RECVIF)
-       {
-         struct sockaddr_dl *ri = (struct sockaddr_dl *) CMSG_DATA(cm);
-         s->lifindex = ri->sdl_index;
-       }
+  if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_RECVIF)
+    {
+      struct sockaddr_dl *ri = (struct sockaddr_dl *) CMSG_DATA(cm);
+      s->lifindex = ri->sdl_index;
     }
 
   // log(L_WARN "RX %I %d", s->laddr, s->lifindex);
@@ -194,8 +151,6 @@ sysio_prepare_tx_cmsgs(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
 }
 */
 
-#endif
-
 
 #include <netinet/tcp.h>
 #ifndef TCP_KEYLEN_MAX
@@ -212,7 +167,7 @@ sysio_prepare_tx_cmsgs(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
  */
 
 static int
-sk_set_md5_auth_int(sock *s, sockaddr *sa, char *passwd)
+sk_set_md5_auth_int(sock *s, struct sockaddr *sa, int sa_len, char *passwd)
 {
   int enable = 0;
   if (passwd)
@@ -242,45 +197,32 @@ sk_set_md5_auth_int(sock *s, sockaddr *sa, char *passwd)
 }
 
 
-#ifndef IPV6
-
 #ifdef IP_MINTTL
 
-static int
+static inline char *
 sk_set_min_ttl4(sock *s, int ttl)
 {
   if (setsockopt(s->fd, IPPROTO_IP, IP_MINTTL, &ttl, sizeof(ttl)) < 0)
-  {
-    if (errno == ENOPROTOOPT)
-      log(L_ERR "Kernel does not support IPv4 TTL security");
-    else
-      log(L_ERR "sk_set_min_ttl4: setsockopt: %m");
+    return "IP_MINTTL";
 
-    return -1;
-  }
-
-  return 0;
+  return NULL;
 }
 
 #else /* no IP_MINTTL */
 
-static int
+static inline char *
 sk_set_min_ttl4(sock *s, int ttl)
 {
-  log(L_ERR "IPv4 TTL security not supported");
-  return -1;
+  errno = ENOPROTOOPT;
+  return "IP_MINTTL";
 }
 
 #endif
 
-#else /* IPv6 */
-
-static int
+static inline char *
 sk_set_min_ttl6(sock *s, int ttl)
 {
-  log(L_ERR "IPv6 TTL security not supported");
-  return -1;
+  errno = ENOPROTOOPT;
+  return "IP_MINTTL";
 }
 
-#endif
-
index 90e164fbb3085fd5a8bcd5ef9d642f9733aae675..e6daa31f8633e26f4289e2a759c464ac54ba54f5 100644 (file)
@@ -220,40 +220,22 @@ sysio_prepare_tx_cmsgs(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
 #define IPV6_MINHOPCOUNT 73
 #endif
 
-
-// XXXX
-#if 0
-
-static int
+static inline char *
 sk_set_min_ttl4(sock *s, int ttl)
 {
   if (setsockopt(s->fd, IPPROTO_IP, IP_MINTTL, &ttl, sizeof(ttl)) < 0)
-  {
-    if (errno == ENOPROTOOPT)
-      log(L_ERR "Kernel does not support IPv4 TTL security");
-    else
-      log(L_ERR "sk_set_min_ttl4: setsockopt: %m");
-
-    return -1;
-  }
+    return "IP_MINTTL";
 
-  return 0;
+  return NULL;
 }
 
-static int
+static inline char *
 sk_set_min_ttl6(sock *s, int ttl)
 {
   if (setsockopt(s->fd, IPPROTO_IPV6, IPV6_MINHOPCOUNT, &ttl, sizeof(ttl)) < 0)
-  {
-    if (errno == ENOPROTOOPT)
-      log(L_ERR "Kernel does not support IPv6 TTL security");
-    else
-      log(L_ERR "sk_set_min_ttl6: setsockopt: %m");
-
-    return -1;
-  }
+    return "IPV6_MINHOPCOUNT";
 
-  return 0;
+  return NULL;
 }
 
-#endif
+
index eb103f1be60377bb86d914a19a1b116d06aaefac..c45e586608461bffb821c3f80e0d235e9af90a67 100644 (file)
@@ -590,23 +590,29 @@ static inline int sockaddr_size(int af)
 static inline void
 sockaddr_fill4(struct sockaddr_in *sa, ip_addr a, struct iface *ifa, unsigned port)
 {
-  sa->sin_port = htons(port);
+  memset(sa, 0, sizeof(struct sockaddr_in));
 #ifdef HAVE_SIN_LEN
   sa->sin_len = sizeof(struct sockaddr_in);
 #endif
+  sa->sin_family = AF_INET;
+  sa->sin_port = htons(port);
   ipa_put_in4(&sa->sin_addr, a);
 }
 
 static inline void
 sockaddr_fill6(struct sockaddr_in6 *sa, ip_addr a, struct iface *ifa, unsigned port)
 {
-  sa->sin6_port = htons(port);
-  sa->sin6_flowinfo = 0;
+  memset(sa, 0, sizeof(struct sockaddr_in6));
 #ifdef SIN6_LEN
   sa->sin6_len = sizeof(struct sockaddr_in6);
 #endif
+  sa->sin6_family = AF_INET6;
+  sa->sin6_port = htons(port);
+  sa->sin6_flowinfo = 0;
   ipa_put_in6(&sa->sin6_addr, a);
-  sa->sin6_scope_id = (ifa && ipa_is_link_local(a)) ? ifa->index : 0;
+
+  if (ifa && ipa_is_link_local(a))
+    sa->sin6_scope_id = ifa->index;
 }
 
 void
@@ -852,24 +858,21 @@ sk_set_min_ttl(sock *s, int ttl)
   char *err;
 
   if (sk_is_ipv4(s))
-    {
-      if (setsockopt(s->fd, IPPROTO_IP, IP_MINTTL, &ttl, sizeof(ttl)) < 0)
-       ERR("IP_MINTTL");
-    }
+    err = sk_set_min_ttl4(s, ttl);
   else
-    {
-      if (setsockopt(s->fd, IPPROTO_IPV6, IPV6_MINHOPCOUNT, &ttl, sizeof(ttl)) < 0)
-       ERR("IPV6_MINHOPCOUNT");
-    }
+    err = sk_set_min_ttl6(s, ttl);
 
-  return 0;
+  if (err)
+  {
+    if (errno == ENOPROTOOPT)
+      log(L_ERR "Kernel does not support %s TTL security", sk_is_ipv4(s) ? "IPv4" : "IPv6");
+    else
+      log(L_ERR "sk_set_min_ttl: %s: %m", err);
 
- bad:
-  if (errno == ENOPROTOOPT)
-    log(L_ERR "Kernel does not support %s TTL security", sk_is_ipv4(s) ? "IPv4" : "IPv6");
-  else
-    log(L_ERR "sk_set_min_ttl: %s: %m", err);
-  return -1;
+    return -1;
+  }
+
+  return 0;
 }
 
 
index efcb87eaa6421b9ff809af27d2dcaeed98890048..3442784714fd5879d177c6e81860e606327a6ae1 100644 (file)
@@ -1062,11 +1062,6 @@ krt_postconfig(struct proto_config *C)
 struct proto_config *
 krt_init_config(int class)
 {
-#ifndef CONFIG_MULTIPLE_TABLES
-  if (krt_cf)
-    cf_error("Kernel protocol already defined");
-#endif
-
   krt_cf = (struct krt_config *) proto_config_new(&proto_unix_kernel, sizeof(struct krt_config), class);
   krt_cf->scan_time = 60;
 
index aca3cc77c0d281ecc609ea3c114d160b2342b887..52bb4fe602c7bdc6dfbdf5cacd1ca62f26e9b8dc 100644 (file)
@@ -33,10 +33,11 @@ volatile int async_config_flag;
 volatile int async_dump_flag;
 volatile int async_shutdown_flag;
 
-// XXXX
-#define BIRD_PF PF_INET6
-#define BIRD_AF AF_INET6
-static inline int sa_family_check(struct sockaddr *sa) { return sa->sa_family == AF_INET6; }
+struct sockaddr;
+struct iface;
+
+void sockaddr_fill(struct sockaddr *sa, ip_addr a, struct iface *ifa, unsigned port);
+void sockaddr_read(struct sockaddr *sa, ip_addr *a, struct iface **ifa, unsigned *port, int check);
 
 
 #ifndef SUN_LEN