diff options
author | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2008-05-02 11:52:42 -0700 |
---|---|---|
committer | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2008-05-02 11:52:42 -0700 |
commit | 64cb6fed376b0f6e91ae8d08a1e0a9658457a8ed (patch) | |
tree | 41443a7bcda0492fe79a0fa473e49d6c59214448 | |
parent | b429bc8a8da1611fca49aca23c3f88c9f7a3c229 (diff) | |
download | quagga-64cb6fed376b0f6e91ae8d08a1e0a9658457a8ed.tar.bz2 quagga-64cb6fed376b0f6e91ae8d08a1e0a9658457a8ed.tar.xz |
filter out all route change responses on listen socket
When zebra changes routes it uses the netlink cmd socket, but these
also show up on the netlink listen socket. Use more kernel level socket
filtering so that any changes that happend because of command socket
are ignored.
Uses the netlink port id (pid) to identify the changes from the
command socket.
-rw-r--r-- | zebra/rt_netlink.c | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 273c3121..f84d6596 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1939,22 +1939,26 @@ kernel_read (struct thread *thread) return 0; } -/* Filter out messages from self that occur on listener socket */ -static void netlink_install_filter (int sock) +/* Filter out messages from self that occur on listener socket, + caused by our actions on the command socket + */ +static void netlink_install_filter (int sock, __u32 pid) { - /* BPF code to exclude all RTM_NEWROUTE messages from ZEBRA */ struct sock_filter filter[] = { + /* 0: ldh [4] */ 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, 0, 1), - /* 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 */ + /* 1: jeq 0x18 jt 3 jf 6 */ + BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_NEWROUTE), 1, 0), + /* 2: jeq 0x19 jt 3 jf 6 */ + BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_DELROUTE), 0, 3), + /* 3: ldw [12] */ + BPF_STMT(BPF_LD|BPF_ABS|BPF_W, offsetof(struct nlmsghdr, nlmsg_pid)), + /* 4: jeq XX jt 5 jf 6 */ + BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htonl(pid), 0, 1), + /* 5: ret 0 (skip) */ + BPF_STMT(BPF_RET|BPF_K, 0), + /* 6: ret 0xffff (keep) */ + BPF_STMT(BPF_RET|BPF_K, 0xffff), }; struct sock_fprog prog = { @@ -1983,7 +1987,7 @@ kernel_init (void) /* Register kernel socket. */ if (netlink.sock > 0) { - netlink_install_filter (netlink.sock); + netlink_install_filter (netlink.sock, netlink_cmd.snl.nl_pid); thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock); } } |