summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <stephen.hemminger@vyatta.com>2008-05-02 11:52:42 -0700
committerStephen Hemminger <stephen.hemminger@vyatta.com>2008-05-02 11:52:42 -0700
commit64cb6fed376b0f6e91ae8d08a1e0a9658457a8ed (patch)
tree41443a7bcda0492fe79a0fa473e49d6c59214448
parentb429bc8a8da1611fca49aca23c3f88c9f7a3c229 (diff)
downloadquagga-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.c32
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);
}
}