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;

Reply via email to