Assorted bugfixes:

+ configuration: make sure that the NUL at the end of the config
   string is properly detected and handled, and the stats passed
   up via sysctl properly reflect which interfaces do bridging.
   (The whole config support might make good use of some cleanup
   in the future).

 + fixed some bugs related to the corruption of multicast and
   broadcast packets: make sure that for those packets the entire
   IP + ethernet header is in the mbuf, not in a cluster, so
   that writes performed in that area by the upper layers do
   not affect us.

 + performance: when calling m_pullup, make room for the ethernet header
   as well, we are going to add it in right after. Also, change an m_dup
   back to m_copypacket. The former is not necessary anymore now, and
   it did not help, anyways.

I will do a fast MFC because 95% of this patch is fixing bad bugs
and i doubt anyone would test the fix in CURRENT. Plus the last
two items mostly bring back some code which was already there in 4.0
times.
This commit is contained in:
Luigi Rizzo 2001-01-22 22:34:53 +00:00
parent 462574faf5
commit bfcd631529
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=71392

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2000 Luigi Rizzo
* Copyright (c) 1998-2001 Luigi Rizzo
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -181,9 +181,11 @@ bdg_promisc_off(int clear_used)
ret = ifpromisc(ifp, 0);
splx(s);
ifp2sc[ifp->if_index].flags &= ~(IFF_BDG_PROMISC|IFF_MUTE) ;
if (clear_used)
if (clear_used) {
ifp2sc[ifp->if_index].flags &= ~(IFF_USED) ;
printf(">> now %s%d promisc ON if_flags 0x%x bdg_flags 0x%x\n",
bdg_stats.s[ifp->if_index].name[0] = '\0';
}
printf(">> now %s%d promisc OFF if_flags 0x%x bdg_flags 0x%x\n",
ifp->if_name, ifp->if_unit,
ifp->if_flags, ifp2sc[ifp->if_index].flags);
}
@ -286,14 +288,16 @@ parse_bdg_cfg()
if (!strncmp(beg, buf, l)) { /* XXX not correct for >10 if! */
b->cluster_id = htons(cluster) ;
b->flags |= IFF_USED ;
sprintf(bdg_stats.s[ifp->if_index].name+l,
":%d", cluster);
sprintf(bdg_stats.s[ifp->if_index].name,
"%s%d:%d", ifp->if_name, ifp->if_unit, cluster);
DDB(printf("--++ found %s\n",
bdg_stats.s[ifp->if_index].name);)
break ;
}
}
if (*p == '\0')
break ;
}
}
@ -700,10 +704,13 @@ bdg_forward(struct mbuf **m0, struct ether_header *const eh, struct ifnet *dst)
*/
if (canfree == 0 ) {
/*
* Need to make a copy (and for good measure, make sure that
* the header is contiguous). The original is still in *m0
* Need to make a copy. The original is still in *m0.
* Make sure that, in the copy, the first mbuf contains
* both the ethernet and the ip header. The reason is,
* some code up in the stack treats the IP header as rw so
* we do not want to share it into a cluster.
*/
int needed = min(MHLEN, max_protohdr) ;
int needed = min(MHLEN, 14+max_protohdr) ;
needed = min(needed, (*m0)->m_len ) ;
m = m_copypacket( (*m0), M_DONTWAIT);
@ -711,7 +718,8 @@ bdg_forward(struct mbuf **m0, struct ether_header *const eh, struct ifnet *dst)
printf("-- bdg: m_copypacket failed.\n") ;
return ENOBUFS ;
}
if (m->m_len < needed && (m = m_pullup(m, needed)) == NULL) {
m = m_pullup(m, needed) ;
if (m == NULL) {
printf("-- bdg: pullup failed.\n") ;
return ENOBUFS ;
}
@ -802,11 +810,12 @@ bdg_forward(struct mbuf **m0, struct ether_header *const eh, struct ifnet *dst)
* but better than having packets corrupt!
*/
if (canfree == 0 ) {
int needed = min(MHLEN, max_protohdr) ;
int needed = min(MHLEN, 14+ max_protohdr) ;
needed = min(needed, (*m0)->m_len ) ;
if ((*m0)->m_len < needed && (*m0 = m_pullup(*m0, needed)) == NULL) {
printf("-- bdg: pullup failed.\n") ;
*m0 = m_pullup(*m0, needed) ;
if ( *m0 == NULL) {
printf("-- bdg: pullup(2) failed.\n") ;
return ENOBUFS ;
}
}
@ -816,9 +825,9 @@ bdg_forward(struct mbuf **m0, struct ether_header *const eh, struct ifnet *dst)
m = *m0 ;
*m0 = NULL ; /* original is gone */
} else
m = m_dup(*m0, M_DONTWAIT); /* XXX m_copypacket should work */
m = m_copypacket(*m0, M_DONTWAIT);
if (m == NULL) {
printf("bdg_forward: sorry, m_dup failed!\n");
printf("bdg_forward: sorry, m_copypacket failed!\n");
return ENOBUFS ; /* the original is still there... */
}
/*