mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 17:48:35 +00:00
[zebra/linux] Use BPF to filter out responses, to try avoid netlink overruns
2008-05-29 Stephen Hemminger <stephen.hemminger@vyatta.com> * rt_netlink.c: (netlink_install_filter) BPF filter to catch and drop responses to zebra's own route messages. (kernel_init) add BPF filter on the netlink socket.
This commit is contained in:
parent
311064ddc5
commit
768a27ea7b
@ -162,6 +162,8 @@ typedef int socklen_t;
|
|||||||
#ifdef HAVE_NETLINK
|
#ifdef HAVE_NETLINK
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
|
#include <linux/filter.h>
|
||||||
|
#include <stddef.h>
|
||||||
#else
|
#else
|
||||||
#define RT_TABLE_MAIN 0
|
#define RT_TABLE_MAIN 0
|
||||||
#endif /* HAVE_NETLINK */
|
#endif /* HAVE_NETLINK */
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
2008-05-29 Stephen Hemminger <stephen.hemminger@vyatta.com>
|
||||||
|
|
||||||
|
* rt_netlink.c: (netlink_install_filter) BPF filter to catch and
|
||||||
|
drop responses to zebra's own route messages.
|
||||||
|
(kernel_init) add BPF filter on the netlink socket.
|
||||||
|
|
||||||
2008-02-26 Denis Ovsienko
|
2008-02-26 Denis Ovsienko
|
||||||
* zebra_rib.[ch]: (rib_lookup_and_pushup) New function, which makes sure,
|
* zebra_rib.[ch]: (rib_lookup_and_pushup) New function, which makes sure,
|
||||||
that if_set_prefix() has nothing in its way of assigning an address.
|
that if_set_prefix() has nothing in its way of assigning an address.
|
||||||
|
@ -1938,6 +1938,56 @@ kernel_read (struct thread *thread)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Filter out messages from self that occur on listener socket */
|
||||||
|
static void netlink_install_filter (int sock)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* 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 */
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
/* Exported interface function. This function simply calls
|
||||||
netlink_socket (). */
|
netlink_socket (). */
|
||||||
void
|
void
|
||||||
@ -1954,5 +2004,8 @@ kernel_init (void)
|
|||||||
|
|
||||||
/* Register kernel socket. */
|
/* Register kernel socket. */
|
||||||
if (netlink.sock > 0)
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user