diff options
Diffstat (limited to 'zebra')
-rw-r--r-- | zebra/interface.c | 10 | ||||
-rw-r--r-- | zebra/rt_netlink.c | 41 | ||||
-rw-r--r-- | zebra/zebra_rib.c | 6 |
3 files changed, 44 insertions, 13 deletions
diff --git a/zebra/interface.c b/zebra/interface.c index 184b42a0..7dc1b68d 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -274,7 +274,7 @@ if_addr_wakeup (struct interface *ifp) /* Address check. */ if (p->family == AF_INET) { - if (! if_is_up (ifp)) + if (! if_is_operative (ifp)) { /* XXX: WTF is it trying to set flags here? * caller has just gotten a new interface, has been @@ -311,7 +311,7 @@ if_addr_wakeup (struct interface *ifp) #ifdef HAVE_IPV6 if (p->family == AF_INET6) { - if (! if_is_up (ifp)) + if (! if_is_operative (ifp)) { /* XXX: See long comment above */ if_set_flags (ifp, IFF_UP | IFF_RUNNING); @@ -379,7 +379,7 @@ if_delete_update (struct interface *ifp) zebra_if = ifp->info; - if (if_is_up(ifp)) + if (if_is_operative(ifp)) { zlog_err ("interface %s index %d is still up while being deleted.", ifp->name, ifp->ifindex); @@ -1205,7 +1205,7 @@ ip_address_install (struct vty *vty, struct interface *ifp, && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) { /* Some system need to up the interface to set IP address. */ - if (! if_is_up (ifp)) + if (! if_is_operative (ifp)) { if_set_flags (ifp, IFF_UP | IFF_RUNNING); if_refresh (ifp); @@ -1398,7 +1398,7 @@ ipv6_address_install (struct vty *vty, struct interface *ifp, && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) { /* Some system need to up the interface to set IP address. */ - if (! if_is_up (ifp)) + if (! if_is_operative (ifp)) { if_set_flags (ifp, IFF_UP | IFF_RUNNING); if_refresh (ifp); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 5b592f94..07e473bc 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -41,6 +41,7 @@ #include "zebra/redistribute.h" #include "zebra/interface.h" #include "zebra/debug.h" +#include <stddef.h> /* Socket interface to kernel */ struct nlsock @@ -103,7 +104,7 @@ set_ifindex(struct interface *ifp, unsigned int ifi_index) if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug("interface index %d was renamed from %s to %s", ifi_index, oifp->name, ifp->name); - if (if_is_up(oifp)) + if (if_is_operative(oifp)) zlog_err("interface rename detected on up interface: index %d " "was renamed from %s to %s, results are uncertain!", ifi_index, oifp->name, ifp->name); @@ -328,7 +329,8 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *), while (1) { - char buf[4096]; + //increased from 4096 to 32768 as recvmsg overrun error + char buf[32768]; struct iovec iov = { buf, sizeof buf }; struct sockaddr_nl snl; struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 }; @@ -1048,7 +1050,7 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h) } else { - /* RTM_DELLINK. */ + // RTM_DELLINK. ifp = if_lookup_by_name (name); if (ifp == NULL) @@ -1060,7 +1062,6 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h) if_delete_update (ifp); } - return 0; } @@ -1938,6 +1939,33 @@ kernel_read (struct thread *thread) return 0; } +/* Filter out messages from self that occur on listener socket */ +static void netlink_install_filter (int sock) +{ + /* BPF code to exclude all RTM_NEWROUTE messages from ZEBRA */ + struct sock_filter filter[] = { + BPF_STMT(BPF_LD|BPF_ABS|BPF_H, offsetof(struct nlmsghdr, nlmsg_type)), + /* 0: ldh [4] */ + BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_NEWROUTE), 0, 3), + /* 1: jeq 0x18 jt 2 jf 5 */ + BPF_STMT(BPF_LD|BPF_ABS|BPF_B, + sizeof(struct nlmsghdr) + offsetof(struct rtmsg, rtm_protocol)), + /* 2: ldb [23] */ + BPF_JUMP(BPF_JMP+ BPF_B, RTPROT_ZEBRA, 2, 0), + /* 3: jeq 0xb jt 4 jf 5 */ + BPF_STMT(BPF_RET|BPF_K, 0), /* 4: ret 0 */ + BPF_STMT(BPF_RET|BPF_K, 0xffff), /* 5: ret 0xffff */ + }; + + struct sock_fprog prog = { + .len = sizeof(filter) / sizeof(filter[0]), + .filter = filter, + }; + + if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog)) < 0) + zlog_warn ("Can't install socket filter: %s\n", safe_strerror(errno)); +} + /* Exported interface function. This function simply calls netlink_socket (). */ void @@ -1954,5 +1982,8 @@ kernel_init (void) /* Register kernel socket. */ if (netlink.sock > 0) - thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock); + { + netlink_install_filter (netlink.sock); + thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock); + } } diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index c6af3290..a4fa261b 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -795,7 +795,7 @@ nexthop_active_check (struct route_node *rn, struct rib *rib, { case NEXTHOP_TYPE_IFINDEX: ifp = if_lookup_by_index (nexthop->ifindex); - if (ifp && if_is_operative(ifp)) + if (ifp && if_is_operative (ifp)) SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); else UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); @@ -804,7 +804,7 @@ nexthop_active_check (struct route_node *rn, struct rib *rib, family = AFI_IP6; case NEXTHOP_TYPE_IFNAME: ifp = if_lookup_by_name (nexthop->ifname); - if (ifp && if_is_operative(ifp)) + if (ifp && if_is_operative (ifp)) { if (set) nexthop->ifindex = ifp->ifindex; @@ -838,7 +838,7 @@ nexthop_active_check (struct route_node *rn, struct rib *rib, if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6)) { ifp = if_lookup_by_index (nexthop->ifindex); - if (ifp && if_is_operative(ifp)) + if (ifp && if_is_operative (ifp)) SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); else UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); |