Source-Changes-D archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: CVS commit: src/sys



>> > > This clearly is a layering/abstraction violation and would have been
>> > > good to discuss upfront.
>> > >
>> > > Where do you make use of that information? What about other packet injection
>> > > paths?
>> >
>> > The next commit uses it in if_arp to ensure that the DaD probe sending interface
>> > hardware address matches the sending hardware address in the ARP packet as
>> > specified in RFC 5227 section 1.1
>> >
>> > I couldn't think of a better way of achieving this.
>>
>> RFC 5227 says senders must follow the spec but doesn't say receivers'
>> check is must IIUC.
>>
>> I don't think it is a good idea to increase the mbuf size just for
>> broken clients.
>> I think it is better to make the strict check optional (by sysctl or
>> something) and use mtag,
>> so the change doesn't impact on most of us.
>
>Well... another possible option is to unionize l2_* with pattr_*.
>This is possible (IIUC)
>because l2_* are used only on receiving packets while pattr_* are used only on
>sending packets.


Since l2_sha continues to point outside of m_data manipulated by m_adj(),
it can be corrupted by subsequent m_pullup() or other mbuf m_*() operations.
I still believe that using MTAG is appropriate.

How about something like this? (not tested)

git diff -u -u .
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 34be2d1cf91..18c8c1dcef9 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -886,9 +886,17 @@ ether_input(struct ifnet *ifp, struct mbuf *m)
 #endif
 	}
 
-	/* Store the senders hardware address */
-	m->m_pkthdr.l2_sha = &eh->ether_shost;
-	m->m_pkthdr.l2_shalen = ETHER_ADDR_LEN;
+	//if (arp_do_strict_check_sha)	/* XXX: sysctl? */
+	if (etype == ETHERTYPE_ARP) {
+		/* Store the senders hardware address */
+		struct m_tag *mtag;
+		mtag = m_tag_get(PACKET_TAG_ETHERNET_SRC, ETHER_ADDR_LEN,
+		    M_NOWAIT);
+		if (mtag != NULL) {
+			memcpy(mtag + 1, &eh->ether_shost, ETHER_ADDR_LEN);
+			m_tag_prepend(m, mtag);
+		}
+	}
 
 	/* Strip off the Ethernet header. */
 	m_adj(m, ehlen);
diff --git a/sys/netinet/if_arp.c b/sys/netinet/if_arp.c
index 90b0be9ff59..3334452c496 100644
--- a/sys/netinet/if_arp.c
+++ b/sys/netinet/if_arp.c
@@ -945,18 +945,23 @@ again:
 	    (in_hosteq(isaddr, myaddr) ||
 	    (in_nullhost(isaddr) && in_hosteq(itaddr, myaddr) &&
 	     m->m_flags & M_BCAST &&
-	     ia->ia4_flags & (IN_IFF_TENTATIVE | IN_IFF_DUPLICATED))) &&
-	    m->m_pkthdr.l2_shalen == ah->ar_hln && (
-	    ah->ar_hln == 0 ||
-	    memcmp(m->m_pkthdr.l2_sha, ar_sha(ah), ah->ar_hln) == 0))
+	     ia->ia4_flags & (IN_IFF_TENTATIVE | IN_IFF_DUPLICATED))))
 	{
 		struct sockaddr_dl sdl, *sdlp;
+		struct m_tag *mtag = NULL;
 
-		sdlp = sockaddr_dl_init(&sdl, sizeof(sdl),
-		    ifp->if_index, ifp->if_type,
-		    NULL, 0, ar_sha(ah), ah->ar_hln);
-		arp_dad_duplicated((struct ifaddr *)ia, sdlp);
-		goto out;
+		//if (arp_do_strict_check_sha)	/* XXX: sysctl? */
+		mtag = m_tag_find(m, PACKET_TAG_ETHERNET_SRC);
+
+		if (mtag == NULL || (ah->ar_hln == ETHER_ADDR_LEN &&
+		    memcmp(mtag + 1, ar_sha(ah), ETHER_ADDR_LEN) == 0)) {
+
+			sdlp = sockaddr_dl_init(&sdl, sizeof(sdl),
+			    ifp->if_index, ifp->if_type,
+			    NULL, 0, ar_sha(ah), ah->ar_hln);
+			arp_dad_duplicated((struct ifaddr *)ia, sdlp);
+			goto out;
+		}
 	}
 
 	/*
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index 6b441b56bd8..bf69372f083 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -178,8 +178,8 @@ struct m_hdr {
  * checksum) -- this is so we can accumulate the checksum for fragmented
  * packets during reassembly.
  *
- * Size ILP32: 48
- *       LP64: 72
+ * Size ILP32: 40
+ *       LP64: 56
  */
 struct pkthdr {
 	union {
@@ -203,9 +203,6 @@ struct pkthdr {
 	int	pattr_af;		/* ALTQ: address family */
 	void	*pattr_class;		/* ALTQ: sched class set by classifier */
 	void	*pattr_hdr;		/* ALTQ: saved header position in mbuf */
-
-	void		*l2_sha;		/* l2 sender host address */
-	size_t		l2_shalen;		/* length of the sender address */
 };
 
 /* Checksumming flags (csum_flags). */
@@ -803,6 +800,7 @@ int	m_tag_copy_chain(struct mbuf *, struct mbuf *);
 					    */
 #define PACKET_TAG_MPLS			29 /* Indicate it's for MPLS */
 #define PACKET_TAG_SRCROUTE		30 /* IPv4 source routing */
+#define PACKET_TAG_ETHERNET_SRC		31
 
 /*
  * Return the number of bytes in the mbuf chain, m.



Since l2_shalen is fixed to ETHER_ADDR_LEN for now, the tag name should be
PACKET_TAG_ETHERNET_SRC instead of PACKET_TAG_L2SHA for now.
If all L2 addresses are to be treated extensively, the structure of mtag
should include the size, but that will not be necessary just yet.

-- 
ryo shimizu


Home | Main Index | Thread Index | Old Index