diff options
Diffstat (limited to 'zebra')
| -rw-r--r-- | zebra/rt_netlink.c | 73 | 
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);      }  }  | 
