summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zebra/rt_netlink.c73
1 files changed, 27 insertions, 46 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 395f1ca6..592dfe2e 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -285,7 +285,7 @@ netlink_request (int family, int type, struct nlsock *nl)
req.nlh.nlmsg_len = sizeof req;
req.nlh.nlmsg_type = type;
req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
- req.nlh.nlmsg_pid = 0;
+ req.nlh.nlmsg_pid = nl->snl.nl_pid;
req.nlh.nlmsg_seq = ++nl->seq;
req.g.rtgen_family = family;
@@ -367,13 +367,6 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
return -1;
}
- /* JF: Ignore messages that aren't from the kernel */
- if ( snl.nl_pid != 0 )
- {
- zlog ( NULL, LOG_ERR, "Ignoring message from pid %u", snl.nl_pid );
- continue;
- }
-
for (h = (struct nlmsghdr *) buf; NLMSG_OK (h, (unsigned int) status);
h = NLMSG_NEXT (h, status))
{
@@ -1066,6 +1059,13 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
static int
netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h)
{
+ /* JF: Ignore messages that aren't from the kernel */
+ if ( snl->nl_pid != 0 )
+ {
+ zlog ( NULL, LOG_ERR, "Ignoring message from pid %u", snl->nl_pid );
+ return 0;
+ }
+
switch (h->nlmsg_type)
{
case RTM_NEWROUTE:
@@ -1935,45 +1935,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)
{
- /*
- * Filter is equivalent to netlink_route_change
- *
- * if (h->nlmsg_type == RTM_DELROUTE || h->nlmsg_type == RTM_NEWROUTE) {
- * if (rtm->rtm_type != RTM_UNICAST)
- * return 0;
- * if (rtm->rtm_flags & RTM_F_CLONED)
- * return 0;
- * if (rtm->rtm_protocol == RTPROT_REDIRECT)
- * return 0;
- * if (rtm->rtm_protocol == RTPROT_KERNEL)
- * return 0;
- * if (rtm->rtm_protocol == RTPROT_ZEBRA && h->nlmsg_type == RTM_NEWROUTE)
- * return 0;
- * }
- * return 0xffff;
- */
struct sock_filter filter[] = {
- /* 0*/ BPF_STMT(BPF_LD|BPF_ABS|BPF_H, offsetof(struct nlmsghdr, nlmsg_type)),
- /* 1*/ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_DELROUTE), 1, 0),
- /* 2*/ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_NEWROUTE), 0, 11),
- /* 3*/ BPF_STMT(BPF_LD|BPF_ABS|BPF_B,
- sizeof(struct nlmsghdr) + offsetof(struct rtmsg, rtm_type)),
- /* 4*/ BPF_JUMP(BPF_JMP|BPF_B, RTN_UNICAST, 0, 8),
- /* 5*/ BPF_STMT(BPF_LD|BPF_ABS|BPF_B,
- sizeof(struct nlmsghdr) + offsetof(struct rtmsg, rtm_flags)),
- /* 6*/ BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, RTM_F_CLONED, 6, 0),
- /* 7*/ BPF_STMT(BPF_LD|BPF_ABS|BPF_B,
- sizeof(struct nlmsghdr) + offsetof(struct rtmsg, rtm_protocol)),
- /* 8*/ BPF_JUMP(BPF_JMP+ BPF_B, RTPROT_REDIRECT, 4, 0),
- /* 9*/ BPF_JUMP(BPF_JMP+ BPF_B, RTPROT_KERNEL, 0, 1),
- /*10*/ BPF_JUMP(BPF_JMP+ BPF_B, RTPROT_ZEBRA, 0, 3),
- /*11*/ BPF_STMT(BPF_LD|BPF_ABS|BPF_H, offsetof(struct nlmsghdr, nlmsg_type)),
- /*12*/ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_NEWROUTE), 0, 1),
- /*13*/ BPF_STMT(BPF_RET|BPF_K, 0), /* drop */
- /*14*/ BPF_STMT(BPF_RET|BPF_K, 0xffff), /* keep */
+ /* 0: ldh [4] */
+ BPF_STMT(BPF_LD|BPF_ABS|BPF_H, offsetof(struct nlmsghdr, nlmsg_type)),
+ /* 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 = {
@@ -2002,7 +1983,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);
}
}