Date: Fri, 11 Aug 2000 17:21:57 -0700 (PDT) From: Archie Cobbs <archie@whistle.com> To: freebsd-net@freebsd.org Cc: wpaul@freebsd.org, rwatson@freebsd.org Subject: SIOCSIFLLADDR ioctl() patch Message-ID: <200008120021.RAA51816@bubba.whistle.com>
next in thread | raw e-mail | index | archive | help
Anyone care to review this patch? I've tried to block a couple of
things that would crash the kernel, e.g., calling SIOCSIFLLADDR
on an interface type that doesn't use struct arpcom in ifp->if_softc.
The ulterior motive is to export if_setlladdr() so that ng_ether(4)
can hook into it.
Thanks,
-Archie
P.S. Is IFT_8021_VLAN ever going to get promoted from if_vlan_var.h
to if_types.h?
___________________________________________________________________________
Archie Cobbs * Whistle Communications, Inc. * http://www.whistle.com
Index: if.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if.c,v
retrieving revision 1.91
diff -u -r1.91 if.c
--- if.c 2000/07/16 01:46:42 1.91
+++ if.c 2000/08/12 00:20:14
@@ -54,6 +54,7 @@
#include <net/if.h>
#include <net/if_arp.h>
#include <net/if_dl.h>
+#include <net/if_types.h>
#include <net/radix.h>
#include <net/route.h>
@@ -762,8 +763,6 @@
{
register struct ifnet *ifp;
register struct ifreq *ifr;
- register struct ifaddr *ifa;
- struct sockaddr_dl *sdl;
struct ifstat *ifs;
int error;
short oif_flags;
@@ -917,29 +916,9 @@
error = suser(p);
if (error)
return (error);
- ifa = ifnet_addrs[ifp->if_index - 1];
- if (ifa == NULL)
- return(EINVAL);
- sdl = (struct sockaddr_dl *)ifa->ifa_addr;
- if (sdl == NULL)
- return(EINVAL);
- bcopy(ifr->ifr_addr.sa_data,
- ((struct arpcom *)ifp->if_softc)->ac_enaddr,
- ifr->ifr_addr.sa_len);
- bcopy(ifr->ifr_addr.sa_data, LLADDR(sdl),
- ifr->ifr_addr.sa_len);
- /*
- * If the interface is already up, we need
- * to re-init it in order to reprogram its
- * address filter.
- */
- if (ifp->if_flags & IFF_UP) {
- ifp->if_flags &= ~IFF_UP;
- (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, NULL);
- ifp->if_flags |= IFF_UP;
- (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, NULL);
- }
- return(0);
+ return if_setlladdr(ifp,
+ ifr->ifr_addr.sa_data, ifr->ifr_addr.sa_len);
+
default:
oif_flags = ifp->if_flags;
if (so->so_proto == 0)
@@ -1337,6 +1316,52 @@
free(ifma, M_IFMADDR);
return 0;
+}
+
+/*
+ * Set the link layer address on an interface.
+ *
+ * At this time we only support certain types of interfaces,
+ * and we don't allow the length of the address to change.
+ */
+int
+if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
+{
+ struct sockaddr_dl *sdl;
+ struct ifaddr *ifa;
+
+ ifa = ifnet_addrs[ifp->if_index - 1];
+ if (ifa == NULL)
+ return (EINVAL);
+ sdl = (struct sockaddr_dl *)ifa->ifa_addr;
+ if (sdl == NULL)
+ return (EINVAL);
+ if (len != sdl->sdl_alen) /* don't allow length to change */
+ return (EINVAL);
+ switch (ifp->if_type) {
+ case IFT_ETHER: /* these types use struct arpcom */
+ case IFT_FDDI:
+ case IFT_XETHER:
+ case IFT_ISO88025:
+ case IFT_PROPVIRTUAL: /* XXX waiting for IFT_8021_VLAN */
+ bcopy(lladdr, ((struct arpcom *)ifp->if_softc)->ac_enaddr, len);
+ bcopy(lladdr, LLADDR(sdl), len);
+ break;
+ default:
+ return (ENODEV);
+ }
+ /*
+ * If the interface is already up, we need
+ * to re-init it in order to reprogram its
+ * address filter.
+ */
+ if ((ifp->if_flags & IFF_UP) != 0) {
+ ifp->if_flags &= ~IFF_UP;
+ (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, NULL);
+ ifp->if_flags |= IFF_UP;
+ (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, NULL);
+ }
+ return (0);
}
struct ifmultiaddr *
Index: if_var.h
===================================================================
RCS file: /home/ncvs/src/sys/net/if_var.h,v
retrieving revision 1.25
diff -u -r1.25 if_var.h
--- if_var.h 2000/07/13 22:54:30 1.25
+++ if_var.h 2000/08/12 00:20:14
@@ -340,6 +340,7 @@
void if_detach __P((struct ifnet *));
void if_down __P((struct ifnet *));
void if_route __P((struct ifnet *, int flag, int fam));
+int if_setlladdr __P((struct ifnet *, const u_char *, int));
void if_unroute __P((struct ifnet *, int flag, int fam));
void if_up __P((struct ifnet *));
/*void ifinit __P((void));*/ /* declared in systm.h for main() */
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200008120021.RAA51816>
