Module Name: src Committed By: knakahara Date: Wed Apr 18 07:40:40 UTC 2018
Modified Files: src/sys/net: if_pppoe.c Log Message: Fix sending PADT to unexpected hosts when net.pppoe.term_unknown is enabled. To generate a diff of this commit: cvs rdiff -u -r1.135 -r1.136 src/sys/net/if_pppoe.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/if_pppoe.c diff -u src/sys/net/if_pppoe.c:1.135 src/sys/net/if_pppoe.c:1.136 --- src/sys/net/if_pppoe.c:1.135 Wed Apr 18 07:36:26 2018 +++ src/sys/net/if_pppoe.c Wed Apr 18 07:40:40 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: if_pppoe.c,v 1.135 2018/04/18 07:36:26 knakahara Exp $ */ +/* $NetBSD: if_pppoe.c,v 1.136 2018/04/18 07:40:40 knakahara Exp $ */ /*- * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.135 2018/04/18 07:36:26 knakahara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.136 2018/04/18 07:40:40 knakahara Exp $"); #ifdef _KERNEL_OPT #include "pppoe.h" @@ -63,6 +63,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v #include <net/if_sppp.h> #include <net/if_spppvar.h> #include <net/if_pppoe.h> +#include <net/if_dl.h> #include <net/bpf.h> @@ -236,6 +237,7 @@ static int pppoe_clone_create(struct if_ static int pppoe_clone_destroy(struct ifnet *); static bool pppoe_term_unknown = false; +static int pppoe_term_unknown_pps = 1; static struct sysctllog *pppoe_sysctl_clog; static void sysctl_net_pppoe_setup(struct sysctllog **); @@ -951,6 +953,16 @@ pppoe_disc_input(struct mbuf *m) m_freem(m); } +static bool +pppoe_is_my_frame(uint8_t *dhost, struct ifnet *rcvif) +{ + + if (memcmp(CLLADDR(rcvif->if_sadl), dhost, ETHER_ADDR_LEN) == 0) + return true; + + return false; +} + static void pppoe_data_input(struct mbuf *m) { @@ -960,13 +972,17 @@ pppoe_data_input(struct mbuf *m) struct ifnet *rcvif; struct psref psref; uint8_t shost[ETHER_ADDR_LEN]; + uint8_t dhost[ETHER_ADDR_LEN]; bool term_unknown = pppoe_term_unknown; KASSERT(m->m_flags & M_PKTHDR); - if (term_unknown) + if (term_unknown) { memcpy(shost, mtod(m, struct ether_header*)->ether_shost, ETHER_ADDR_LEN); + memcpy(dhost, mtod(m, struct ether_header*)->ether_dhost, + ETHER_ADDR_LEN); + } m_adj(m, sizeof(struct ether_header)); if (m->m_pkthdr.len <= PPPOE_HEADERLEN) { printf("pppoe (data): dropping too short packet: %d bytes\n", @@ -998,9 +1014,20 @@ pppoe_data_input(struct mbuf *m) sc = pppoe_find_softc_by_session(session, rcvif, RW_READER); if (sc == NULL) { if (term_unknown) { - printf("pppoe: input for unknown session %#x, " - "sending PADT\n", session); - pppoe_send_padt(rcvif, session, shost); + static struct timeval lasttime = {0, 0}; + static int curpps = 0; + /* + * avoid to send wrong PADT which is response from + * session stage pakcets for other hosts when parent + * ethernet is promiscuous mode. + */ + if (pppoe_is_my_frame(dhost, rcvif) + && ppsratecheck(&lasttime, &curpps, + pppoe_term_unknown_pps)) { + printf("pppoe: input for unknown session %#x, " + "sending PADT\n", session); + pppoe_send_padt(rcvif, session, shost); + } } m_put_rcvif_psref(rcvif, &psref); goto drop;