diff options
author | Michael Larson <slioch@eng-140.vyatta.com> | 2008-03-31 13:54:48 -0700 |
---|---|---|
committer | Michael Larson <slioch@eng-140.vyatta.com> | 2008-03-31 13:54:48 -0700 |
commit | b788be3f9b20f44ceb463e93977fe5731141ef26 (patch) | |
tree | fa6d406f071648674727d120575fac803554575d | |
parent | e11fac98b244ce836185a452bf1960cedf26660c (diff) | |
parent | 2bc693173112ea436884aca19352624504e2246a (diff) | |
download | quagga-b788be3f9b20f44ceb463e93977fe5731141ef26.tar.bz2 quagga-b788be3f9b20f44ceb463e93977fe5731141ef26.tar.xz |
Merge branch 'master' of http://git.vyatta.com/vyatta-quagga
-rw-r--r-- | lib/zebra.h | 1 | ||||
-rw-r--r-- | zebra/rt_netlink.c | 33 |
2 files changed, 33 insertions, 1 deletions
diff --git a/lib/zebra.h b/lib/zebra.h index 150aa2c5..d4f68cf0 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -162,6 +162,7 @@ typedef int socklen_t; #ifdef HAVE_NETLINK #include <linux/netlink.h> #include <linux/rtnetlink.h> +#include <linux/filter.h> #else #define RT_TABLE_MAIN 0 #endif /* HAVE_NETLINK */ diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index f071eb24..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 @@ -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); + } } |