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;