summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
Diffstat (limited to 'zebra')
-rw-r--r--zebra/interface.c18
-rw-r--r--zebra/interface.h10
-rw-r--r--zebra/kernel_socket.c43
-rw-r--r--zebra/rt_netlink.c65
-rw-r--r--zebra/rtadv.c19
-rw-r--r--zebra/zserv.c5
6 files changed, 114 insertions, 46 deletions
diff --git a/zebra/interface.c b/zebra/interface.c
index 411712d5..8a9225ac 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -705,9 +705,6 @@ nd_dump_vty (struct vty *vty, struct interface *ifp)
static void
if_dump_vty (struct vty *vty, struct interface *ifp)
{
-#ifdef HAVE_STRUCT_SOCKADDR_DL
- struct sockaddr_dl *sdl;
-#endif /* HAVE_STRUCT_SOCKADDR_DL */
struct connected *connected;
struct listnode *node;
struct route_node *rn;
@@ -759,19 +756,7 @@ if_dump_vty (struct vty *vty, struct interface *ifp)
if_flag_dump (ifp->flags), VTY_NEWLINE);
/* Hardware address. */
-#ifdef HAVE_STRUCT_SOCKADDR_DL
- sdl = &ifp->sdl;
- if (sdl != NULL && sdl->sdl_alen != 0)
- {
- int i;
- u_char *ptr;
-
- vty_out (vty, " HWaddr: ");
- for (i = 0, ptr = (u_char *)LLADDR (sdl); i < sdl->sdl_alen; i++, ptr++)
- vty_out (vty, "%s%02x", i == 0 ? "" : ":", *ptr);
- vty_out (vty, "%s", VTY_NEWLINE);
- }
-#else
+ vty_out (vty, " Type: %s%s", if_link_type_str (ifp->ll_type), VTY_NEWLINE);
if (ifp->hw_addr_len != 0)
{
int i;
@@ -781,7 +766,6 @@ if_dump_vty (struct vty *vty, struct interface *ifp)
vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]);
vty_out (vty, "%s", VTY_NEWLINE);
}
-#endif /* HAVE_STRUCT_SOCKADDR_DL */
/* Bandwidth in kbps */
if (ifp->bandwidth != 0)
diff --git a/zebra/interface.h b/zebra/interface.h
index 936156eb..dbb33c55 100644
--- a/zebra/interface.h
+++ b/zebra/interface.h
@@ -196,6 +196,16 @@ struct zebra_if
struct irdp_interface irdp;
#endif
+#ifdef HAVE_STRUCT_SOCKADDR_DL
+ union {
+ /* note that sdl_storage is never accessed, it only exists to make space.
+ * all actual uses refer to sdl - but use sizeof(sdl_storage)! this fits
+ * best with C aliasing rules. */
+ struct sockaddr_dl sdl;
+ struct sockaddr_storage sdl_storage;
+ };
+#endif
+
#ifdef SUNOS_5
/* the real IFF_UP state of the primary interface.
* need this to differentiate between all interfaces being
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index ba03498c..10cc48c4 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -20,6 +20,7 @@
*/
#include <zebra.h>
+#include <net/if_types.h>
#include "if.h"
#include "prefix.h"
@@ -378,6 +379,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
@@ -534,14 +558,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);
}
@@ -1099,7 +1132,7 @@ 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)
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 930271d0..b164c7ac 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -20,6 +20,7 @@
*/
#include <zebra.h>
+#include <net/if_arp.h>
/* Hack for GNU libc version 2. */
#ifndef MSG_TRUNC
@@ -462,6 +463,68 @@ netlink_interface_update_hw_addr (struct rtattr **tb, struct interface *ifp)
}
}
+static enum zebra_link_type
+netlink_to_zebra_link_type (unsigned int hwt)
+{
+ switch (hwt)
+ {
+ case ARPHRD_ETHER: return ZEBRA_LLT_ETHER;
+ case ARPHRD_EETHER: return ZEBRA_LLT_EETHER;
+ case ARPHRD_AX25: return ZEBRA_LLT_AX25;
+ case ARPHRD_PRONET: return ZEBRA_LLT_PRONET;
+ case ARPHRD_IEEE802: return ZEBRA_LLT_IEEE802;
+ case ARPHRD_ARCNET: return ZEBRA_LLT_ARCNET;
+ case ARPHRD_APPLETLK: return ZEBRA_LLT_APPLETLK;
+ case ARPHRD_DLCI: return ZEBRA_LLT_DLCI;
+ case ARPHRD_ATM: return ZEBRA_LLT_ATM;
+ case ARPHRD_METRICOM: return ZEBRA_LLT_METRICOM;
+ case ARPHRD_IEEE1394: return ZEBRA_LLT_IEEE1394;
+ case ARPHRD_EUI64: return ZEBRA_LLT_EUI64;
+ case ARPHRD_INFINIBAND: return ZEBRA_LLT_INFINIBAND;
+ case ARPHRD_SLIP: return ZEBRA_LLT_SLIP;
+ case ARPHRD_CSLIP: return ZEBRA_LLT_CSLIP;
+ case ARPHRD_SLIP6: return ZEBRA_LLT_SLIP6;
+ case ARPHRD_CSLIP6: return ZEBRA_LLT_CSLIP6;
+ case ARPHRD_RSRVD: return ZEBRA_LLT_RSRVD;
+ case ARPHRD_ADAPT: return ZEBRA_LLT_ADAPT;
+ case ARPHRD_ROSE: return ZEBRA_LLT_ROSE;
+ case ARPHRD_X25: return ZEBRA_LLT_X25;
+ case ARPHRD_PPP: return ZEBRA_LLT_PPP;
+ case ARPHRD_CISCO: return ZEBRA_LLT_CHDLC;
+ case ARPHRD_LAPB: return ZEBRA_LLT_LAPB;
+ case ARPHRD_RAWHDLC: return ZEBRA_LLT_RAWHDLC;
+ case ARPHRD_TUNNEL: return ZEBRA_LLT_IPIP;
+ case ARPHRD_TUNNEL6: return ZEBRA_LLT_IPIP6;
+ case ARPHRD_FRAD: return ZEBRA_LLT_FRAD;
+ case ARPHRD_SKIP: return ZEBRA_LLT_SKIP;
+ case ARPHRD_LOOPBACK: return ZEBRA_LLT_LOOPBACK;
+ case ARPHRD_LOCALTLK: return ZEBRA_LLT_LOCALTLK;
+ case ARPHRD_FDDI: return ZEBRA_LLT_FDDI;
+ case ARPHRD_SIT: return ZEBRA_LLT_SIT;
+ case ARPHRD_IPDDP: return ZEBRA_LLT_IPDDP;
+ case ARPHRD_IPGRE: return ZEBRA_LLT_IPGRE;
+ case ARPHRD_PIMREG: return ZEBRA_LLT_PIMREG;
+ case ARPHRD_HIPPI: return ZEBRA_LLT_HIPPI;
+ case ARPHRD_ECONET: return ZEBRA_LLT_ECONET;
+ case ARPHRD_IRDA: return ZEBRA_LLT_IRDA;
+ case ARPHRD_FCPP: return ZEBRA_LLT_FCPP;
+ case ARPHRD_FCAL: return ZEBRA_LLT_FCAL;
+ case ARPHRD_FCPL: return ZEBRA_LLT_FCPL;
+ case ARPHRD_FCFABRIC: return ZEBRA_LLT_FCFABRIC;
+ case ARPHRD_IEEE802_TR: return ZEBRA_LLT_IEEE802_TR;
+ case ARPHRD_IEEE80211: return ZEBRA_LLT_IEEE80211;
+ case ARPHRD_IEEE802154: return ZEBRA_LLT_IEEE802154;
+#ifdef ARPHRD_IP6GRE
+ case ARPHRD_IP6GRE: return ZEBRA_LLT_IP6GRE;
+#endif
+#ifdef ARPHRD_IEEE802154_PHY
+ case ARPHRD_IEEE802154_PHY: return ZEBRA_LLT_IEEE802154_PHY;
+#endif
+
+ default: return ZEBRA_LLT_UNKNOWN;
+ }
+}
+
/* Called from interface_lookup_netlink(). This function is only used
during bootstrap. */
static int
@@ -509,7 +572,7 @@ netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h,
ifp->metric = 0;
/* Hardware type and address. */
- ifp->hw_type = ifi->ifi_type;
+ ifp->ll_type = netlink_to_zebra_link_type (ifi->ifi_type);
netlink_interface_update_hw_addr (tb, ifp);
if_add_update (ifp);
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index 6b49cf62..7bb93055 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -294,24 +294,6 @@ rtadv_send_packet (int sock, struct interface *ifp)
}
/* Hardware address. */
-#ifdef HAVE_STRUCT_SOCKADDR_DL
- sdl = &ifp->sdl;
- if (sdl != NULL && sdl->sdl_alen != 0)
- {
- buf[len++] = ND_OPT_SOURCE_LINKADDR;
-
- /* Option length should be rounded up to next octet if
- the link address does not end on an octet boundary. */
- buf[len++] = (sdl->sdl_alen + 9) >> 3;
-
- memcpy (buf + len, LLADDR (sdl), sdl->sdl_alen);
- len += sdl->sdl_alen;
-
- /* Pad option to end on an octet boundary. */
- memset (buf + len, 0, -(sdl->sdl_alen + 2) & 0x7);
- len += -(sdl->sdl_alen + 2) & 0x7;
- }
-#else
if (ifp->hw_addr_len != 0)
{
buf[len++] = ND_OPT_SOURCE_LINKADDR;
@@ -327,7 +309,6 @@ rtadv_send_packet (int sock, struct interface *ifp)
memset (buf + len, 0, -(ifp->hw_addr_len + 2) & 0x7);
len += -(ifp->hw_addr_len + 2) & 0x7;
}
-#endif /* HAVE_STRUCT_SOCKADDR_DL */
/* MTU */
if (zif->rtadv.AdvLinkMTU)
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 600b0e5c..2fd10d9b 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -154,13 +154,10 @@ zserv_encode_interface (struct stream *s, struct interface *ifp)
stream_putl (s, ifp->mtu);
stream_putl (s, ifp->mtu6);
stream_putl (s, ifp->bandwidth);
-#ifdef HAVE_STRUCT_SOCKADDR_DL
- stream_put (s, &ifp->sdl, sizeof (ifp->sdl_storage));
-#else
+ stream_putl (s, ifp->ll_type);
stream_putl (s, ifp->hw_addr_len);
if (ifp->hw_addr_len)
stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
-#endif /* HAVE_STRUCT_SOCKADDR_DL */
/* Write packet size. */
stream_putw_at (s, 0, stream_get_endp (s));