forecast: Only reinject packets that are marked or from the configured interface

This seems to avoid broadcast loops (i.e. processing and reinjecting the
same broadcast packet over and over again) as the packets we send via
AF_PACKET socket are neither marked nor from that interface.
This commit is contained in:
Tobias Brunner 2019-02-05 17:21:21 +01:00
parent 00a953d090
commit 83674787d5

View File

@ -317,9 +317,15 @@ static void join_groups(private_kernel_listener_t *this, struct sockaddr *addr)
/**
* Attach the socket filter to the socket
*/
static bool attach_filter(int fd, uint32_t broadcast)
static bool attach_filter(int fd, uint32_t broadcast, uint32_t ifindex)
{
struct sock_filter filter_code[] = {
/* handle any marked packets (from clients) */
BPF_STMT(BPF_LD+BPF_B+BPF_ABS, SKF_AD_OFF+SKF_AD_MARK),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 2),
/* and those from the internal interface */
BPF_STMT(BPF_LD+BPF_B+BPF_ABS, SKF_AD_OFF+SKF_AD_IFINDEX),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ifindex, 0, 5),
/* destination address: is ... */
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct iphdr, daddr)),
/* broadcast, as received from the local network */
@ -390,7 +396,7 @@ static void setup_interface(private_kernel_listener_t *this)
DBG1(DBG_NET, "using forecast interface %s", current->ifa_name);
this->ifindex = get_ifindex(this, current->ifa_name);
in = (struct sockaddr_in*)current->ifa_broadaddr;
attach_filter(this->pkt, in->sin_addr.s_addr);
attach_filter(this->pkt, in->sin_addr.s_addr, this->ifindex);
join_groups(this, current->ifa_addr);
host = host_create_from_sockaddr(current->ifa_broadaddr);
if (host)