summaryrefslogtreecommitdiff
path: root/zebra/kernel_socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/kernel_socket.c')
-rw-r--r--zebra/kernel_socket.c125
1 files changed, 92 insertions, 33 deletions
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index b47ee787e8..6cb9f78598 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -20,12 +20,17 @@
*/
#include <zebra.h>
+#include <net/if_types.h>
+#ifdef __OpenBSD__
+#include <netmpls/mpls.h>
+#endif
#include "if.h"
#include "prefix.h"
#include "sockunion.h"
#include "connected.h"
#include "memory.h"
+#include "zebra_memory.h"
#include "ioctl.h"
#include "log.h"
#include "str.h"
@@ -240,7 +245,9 @@ static const struct message rtm_flag_str[] =
#ifdef RTF_CLONING
{RTF_CLONING, "CLONING"},
#endif /* RTF_CLONING */
+#ifdef RTF_XRESOLVE
{RTF_XRESOLVE, "XRESOLVE"},
+#endif /* RTF_XRESOLVE */
#ifdef RTF_LLINFO
{RTF_LLINFO, "LLINFO"},
#endif /* RTF_LLINFO */
@@ -377,6 +384,29 @@ bsd_linkdetect_translate (struct if_msghdr *ifm)
}
#endif /* HAVE_BSD_IFI_LINK_STATE */
+static enum zebra_link_type
+sdl_to_zebra_link_type (unsigned int sdlt)
+{
+ switch (sdlt)
+ {
+ case IFT_ETHER: return ZEBRA_LLT_ETHER;
+ case IFT_X25: return ZEBRA_LLT_X25;
+ case IFT_FDDI: return ZEBRA_LLT_FDDI;
+ case IFT_PPP: return ZEBRA_LLT_PPP;
+ case IFT_LOOP: return ZEBRA_LLT_LOOPBACK;
+ case IFT_SLIP: return ZEBRA_LLT_SLIP;
+ case IFT_ARCNET: return ZEBRA_LLT_ARCNET;
+ case IFT_ATM: return ZEBRA_LLT_ATM;
+ case IFT_LOCALTALK: return ZEBRA_LLT_LOCALTLK;
+ case IFT_HIPPI: return ZEBRA_LLT_HIPPI;
+#ifdef IFT_IEEE1394
+ case IFT_IEEE1394: return ZEBRA_LLT_IEEE1394;
+#endif
+
+ default: return ZEBRA_LLT_UNKNOWN;
+ }
+}
+
/*
* Handle struct if_msghdr obtained from reading routing socket or
* sysctl (from interface_list). There may or may not be sockaddrs
@@ -533,14 +563,23 @@ ifm_read (struct if_msghdr *ifm)
* is fine here.
* a nonzero ifnlen from RTA_NAME_GET() means sdl is valid
*/
+ ifp->ll_type = ZEBRA_LLT_UNKNOWN;
+ ifp->hw_addr_len = 0;
if (ifnlen)
- {
+ {
#ifdef HAVE_STRUCT_SOCKADDR_DL_SDL_LEN
- memcpy (&ifp->sdl, sdl, sdl->sdl_len);
+ memcpy (&((struct zebra_if *)ifp->info)->sdl, sdl, sdl->sdl_len);
#else
- memcpy (&ifp->sdl, sdl, sizeof (struct sockaddr_dl));
+ memcpy (&((struct zebra_if *)ifp->info)->sdl, sdl, sizeof (struct sockaddr_dl));
#endif /* HAVE_STRUCT_SOCKADDR_DL_SDL_LEN */
- }
+
+ ifp->ll_type = sdl_to_zebra_link_type (sdl->sdl_type);
+ if (sdl->sdl_alen <= sizeof(ifp->hw_addr))
+ {
+ memcpy (ifp->hw_addr, LLADDR(sdl), sdl->sdl_alen);
+ ifp->hw_addr_len = sdl->sdl_alen;
+ }
+ }
if_add_update (ifp);
}
@@ -860,7 +899,7 @@ rtm_read (struct rt_msghdr *rtm)
return;
#endif
- if ((rtm->rtm_type == RTM_ADD) && ! (flags & RTF_UP))
+ if ((rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) && ! (flags & RTF_UP))
return;
/* This is connected route. */
@@ -882,10 +921,10 @@ rtm_read (struct rt_msghdr *rtm)
if (dest.sa.sa_family == AF_INET)
{
- struct prefix_ipv4 p;
+ struct prefix p;
p.family = AF_INET;
- p.prefix = dest.sin.sin_addr;
+ p.u.prefix4 = dest.sin.sin_addr;
if (flags & RTF_HOST)
p.prefixlen = IPV4_MAX_PREFIXLEN;
else
@@ -925,7 +964,7 @@ rtm_read (struct rt_msghdr *rtm)
case ZEBRA_RIB_FOUND_EXACT: /* RIB RR == FIB RR */
zlog_debug ("%s: %s %s: done Ok",
__func__, lookup (rtm_type_str, rtm->rtm_type), buf);
- rib_lookup_and_dump (&p);
+ rib_lookup_and_dump (&p, VRF_DEFAULT);
return;
break;
}
@@ -938,18 +977,18 @@ rtm_read (struct rt_msghdr *rtm)
case ZEBRA_RIB_FOUND_EXACT:
zlog_debug ("%s: %s %s: desync: RR is still in RIB, while already not in FIB",
__func__, lookup (rtm_type_str, rtm->rtm_type), buf);
- rib_lookup_and_dump (&p);
+ rib_lookup_and_dump (&p, VRF_DEFAULT);
break;
case ZEBRA_RIB_FOUND_CONNECTED:
case ZEBRA_RIB_FOUND_NOGATE:
zlog_debug ("%s: %s %s: desync: RR is still in RIB, plus gate differs",
__func__, lookup (rtm_type_str, rtm->rtm_type), buf);
- rib_lookup_and_dump (&p);
+ rib_lookup_and_dump (&p, VRF_DEFAULT);
break;
case ZEBRA_RIB_NOTFOUND: /* RIB RR == FIB RR */
zlog_debug ("%s: %s %s: done Ok",
__func__, lookup (rtm_type_str, rtm->rtm_type), buf);
- rib_lookup_and_dump (&p);
+ rib_lookup_and_dump (&p, VRF_DEFAULT);
return;
break;
}
@@ -965,19 +1004,19 @@ rtm_read (struct rt_msghdr *rtm)
* to specify the route really
*/
if (rtm->rtm_type == RTM_CHANGE)
- rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p,
- NULL, 0, VRF_DEFAULT, SAFI_UNICAST);
+ rib_delete (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
+ 0, zebra_flags, &p, NULL, 0, 0);
+ union g_addr ggate = { .ipv4 = gate.sin.sin_addr };
if (rtm->rtm_type == RTM_GET
|| rtm->rtm_type == RTM_ADD
|| rtm->rtm_type == RTM_CHANGE)
- rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
- &p, &gate.sin.sin_addr, NULL, 0, VRF_DEFAULT, 0, 0, 0, SAFI_UNICAST);
+ rib_add (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
+ &p, &ggate, NULL, 0, 0, 0, 0, 0);
else
- rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0 zebra_flags,
- &p, &gate.sin.sin_addr, 0, VRF_DEFAULT, SAFI_UNICAST);
+ rib_delete (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
+ 0, zebra_flags, &p, &ggate, 0, 0);
}
-#ifdef HAVE_IPV6
if (dest.sa.sa_family == AF_INET6)
{
/* One day we might have a debug section here like one in the
@@ -985,11 +1024,11 @@ rtm_read (struct rt_msghdr *rtm)
*/
if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid)
return;
- struct prefix_ipv6 p;
- unsigned int ifindex = 0;
+ struct prefix p;
+ ifindex_t ifindex = 0;
p.family = AF_INET6;
- p.prefix = dest.sin6.sin6_addr;
+ p.u.prefix6 = dest.sin6.sin6_addr;
if (flags & RTF_HOST)
p.prefixlen = IPV6_MAX_PREFIXLEN;
else
@@ -1007,19 +1046,20 @@ rtm_read (struct rt_msghdr *rtm)
* to specify the route really
*/
if (rtm->rtm_type == RTM_CHANGE)
- rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p,
- NULL, 0, VRF_DEFAULT, SAFI_UNICAST);
-
+ rib_delete (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
+ 0, zebra_flags, &p, NULL, 0, 0);
+
+ union g_addr ggate = { .ipv6 = gate.sin6.sin6_addr };
if (rtm->rtm_type == RTM_GET
|| rtm->rtm_type == RTM_ADD
|| rtm->rtm_type == RTM_CHANGE)
- rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
- &p, &gate.sin6.sin6_addr, ifindex, VRF_DEFAULT, 0, 0, SAFI_UNICAST);
+ rib_add (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
+ 0, zebra_flags, &p, &ggate, NULL, ifindex,
+ 0, 0, 0, 0);
else
- rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
- &p, &gate.sin6.sin6_addr, ifindex, VRF_DEFAULT, SAFI_UNICAST);
+ rib_delete (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
+ 0, zebra_flags, &p, &ggate, ifindex, 0);
}
-#endif /* HAVE_IPV6 */
}
/* Interface function for the kernel routing table updates. Support
@@ -1031,6 +1071,7 @@ rtm_write (int message,
union sockunion *dest,
union sockunion *mask,
union sockunion *gate,
+ union sockunion *mpls,
unsigned int index,
int zebra_flags,
int metric)
@@ -1060,6 +1101,10 @@ rtm_write (int message,
msg.rtm.rtm_addrs = RTA_DST;
msg.rtm.rtm_addrs |= RTA_GATEWAY;
msg.rtm.rtm_flags = RTF_UP;
+#ifdef __OpenBSD__
+ msg.rtm.rtm_flags |= RTF_MPATH;
+ msg.rtm.rtm_fmask = RTF_MPLS;
+#endif
msg.rtm.rtm_index = index;
if (metric != 0)
@@ -1070,14 +1115,14 @@ rtm_write (int message,
ifp = if_lookup_by_index (index);
- if (gate && message == RTM_ADD)
+ if (gate && (message == RTM_ADD || message == RTM_CHANGE))
msg.rtm.rtm_flags |= RTF_GATEWAY;
/* When RTF_CLONING is unavailable on BSD, should we set some
* other flag instead?
*/
#ifdef RTF_CLONING
- if (! gate && message == RTM_ADD && ifp &&
+ if (! gate && (message == RTM_ADD || message == RTM_CHANGE) && ifp &&
(ifp->flags & IFF_POINTOPOINT) == 0)
msg.rtm.rtm_flags |= RTF_CLONING;
#endif /* RTF_CLONING */
@@ -1097,14 +1142,25 @@ rtm_write (int message,
__func__, dest_buf, mask_buf, index);
return -1;
}
- gate = (union sockunion *) & ifp->sdl;
+ gate = (union sockunion *) &((struct zebra_if *)ifp->info)->sdl;
}
if (mask)
msg.rtm.rtm_addrs |= RTA_NETMASK;
- else if (message == RTM_ADD)
+ else if (message == RTM_ADD || message == RTM_CHANGE)
msg.rtm.rtm_flags |= RTF_HOST;
+#ifdef __OpenBSD__
+ if (mpls)
+ {
+ msg.rtm.rtm_addrs |= RTA_SRC;
+ msg.rtm.rtm_flags |= RTF_MPLS;
+
+ if (mpls->smpls.smpls_label != htonl (MPLS_IMP_NULL_LABEL << MPLS_LABEL_OFFSET))
+ msg.rtm.rtm_mpls = MPLS_OP_PUSH;
+ }
+#endif
+
/* Tagging route with flags */
msg.rtm.rtm_flags |= (RTF_PROTO1);
@@ -1129,6 +1185,9 @@ rtm_write (int message,
SOCKADDRSET (dest, RTA_DST);
SOCKADDRSET (gate, RTA_GATEWAY);
SOCKADDRSET (mask, RTA_NETMASK);
+#ifdef __OpenBSD__
+ SOCKADDRSET (mpls, RTA_SRC);
+#endif
msg.rtm.rtm_msglen = pnt - (caddr_t) &msg;