diff options
Diffstat (limited to 'sys/netgraph')
-rw-r--r-- | sys/netgraph/ng_base.c | 24 | ||||
-rw-r--r-- | sys/netgraph/ng_eiface.c | 53 | ||||
-rw-r--r-- | sys/netgraph/ng_eiface.h | 1 | ||||
-rw-r--r-- | sys/netgraph/ng_iface.c | 58 | ||||
-rw-r--r-- | sys/netgraph/ng_iface.h | 1 | ||||
-rw-r--r-- | sys/netgraph/ng_message.h | 1 |
6 files changed, 138 insertions, 0 deletions
diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c index cc2d2d6..693b3ac 100644 --- a/sys/netgraph/ng_base.c +++ b/sys/netgraph/ng_base.c @@ -64,6 +64,10 @@ #include <sys/unistd.h> #include <machine/cpu.h> +#include <sys/socket.h> +#include <net/if.h> +#include <net/if_var.h> + #include <net/netisr.h> #include <net/vnet.h> @@ -240,6 +244,8 @@ int ng_path_parse(char *addr, char **node, char **path, char **hook); void ng_rmnode(node_p node, hook_p dummy1, void *dummy2, int dummy3); void ng_unname(node_p node); +extern void (*ng_ether_attach_p)(struct ifnet *ifp); + /* Our own netgraph malloc type */ MALLOC_DEFINE(M_NETGRAPH, "netgraph", "netgraph structures and ctrl messages"); MALLOC_DEFINE(M_NETGRAPH_MSG, "netgraph_msg", "netgraph name storage"); @@ -574,6 +580,13 @@ static const struct ng_cmdlist ng_generic_cmds[] = { &ng_parse_ng_mesg_type, &ng_parse_ng_mesg_type }, + { + NGM_GENERIC_COOKIE, + NGM_ETHER_ATTACH, + "attach", + &ng_parse_string_type, + NULL + }, { 0 } }; @@ -2908,6 +2921,17 @@ ng_generic_msg(node_p here, item_p item, hook_p lasthook) break; } + case NGM_ETHER_ATTACH: + { + struct ifnet *ifp; + ifp = ifunit((char *)msg->data); + if (ifp && ng_ether_attach_p != NULL) { + ng_ether_attach_p(ifp); + } + + break; + } + case NGM_TEXT_CONFIG: case NGM_TEXT_STATUS: /* diff --git a/sys/netgraph/ng_eiface.c b/sys/netgraph/ng_eiface.c index 0f471bb..24a8daa 100644 --- a/sys/netgraph/ng_eiface.c +++ b/sys/netgraph/ng_eiface.c @@ -43,6 +43,7 @@ #include <net/if.h> #include <net/if_media.h> #include <net/if_types.h> +#include <net/if_dl.h> #include <net/netisr.h> #include <net/route.h> #include <net/vnet.h> @@ -66,6 +67,13 @@ static const struct ng_cmdlist ng_eiface_cmdlist[] = { }, { NGM_EIFACE_COOKIE, + NGM_EIFACE_SET_IFNAME, + "setifname", + &ng_parse_string_type, + NULL + }, + { + NGM_EIFACE_COOKIE, NGM_EIFACE_SET, "set", &ng_parse_enaddr_type, @@ -470,6 +478,11 @@ ng_eiface_rcvmsg(node_p node, item_p item, hook_p lasthook) struct ng_mesg *resp = NULL; int error = 0; struct ng_mesg *msg; + char *new_name; + size_t namelen, onamelen; + struct sockaddr_dl *sdl = NULL; + struct ifaddr *ifa = NULL; + node_p ethernode; NGI_GET_MSG(item, msg); switch (msg->header.typecookie) { @@ -496,6 +509,46 @@ ng_eiface_rcvmsg(node_p node, item_p item, hook_p lasthook) } strlcpy(resp->data, ifp->if_xname, IFNAMSIZ); break; + case NGM_EIFACE_SET_IFNAME: + new_name = (char *)msg->data; + + /* Deny request if interface is UP */ + if ((ifp->if_flags & IFF_UP) != 0) { + error = EBUSY; + break; + } + + EVENTHANDLER_INVOKE(ifnet_departure_event, ifp); + + ethernode = ng_name2noderef(node, ifp->if_xname); + if (ethernode != NULL) + ng_name_node(ethernode, new_name); + + strlcpy(ifp->if_xname, new_name, sizeof(ifp->if_xname)); + ifa = ifp->if_addr; + IFA_LOCK(ifa); + sdl = (struct sockaddr_dl *)ifa->ifa_addr; + namelen = strlen(new_name) + 1; + onamelen = sdl->sdl_nlen; + /* + * Move the address if needed. This is safe because we + * allocate space for a name of length IFNAMSIZ when we + * create this in if_attach(). + */ + if (namelen != onamelen) { + bcopy(sdl->sdl_data + onamelen, + sdl->sdl_data + namelen, sdl->sdl_alen); + } + bcopy(new_name, sdl->sdl_data, namelen); + sdl->sdl_nlen = namelen; + sdl = (struct sockaddr_dl *)ifa->ifa_netmask; + bzero(sdl->sdl_data, onamelen); + while (namelen != 0) + sdl->sdl_data[--namelen] = 0xff; + IFA_UNLOCK(ifa); + + EVENTHANDLER_INVOKE(ifnet_arrival_event, ifp); + break; case NGM_EIFACE_GET_IFADDRS: { diff --git a/sys/netgraph/ng_eiface.h b/sys/netgraph/ng_eiface.h index 6fc1c5b..9f1509b 100644 --- a/sys/netgraph/ng_eiface.h +++ b/sys/netgraph/ng_eiface.h @@ -54,6 +54,7 @@ enum { NGM_EIFACE_GET_IFNAME = 1, /* get the interface name */ NGM_EIFACE_GET_IFADDRS, /* returns list of addresses */ NGM_EIFACE_SET, /* set ethernet address */ + NGM_EIFACE_SET_IFNAME, }; #endif /* _NETGRAPH_NG_EIFACE_H_ */ diff --git a/sys/netgraph/ng_iface.c b/sys/netgraph/ng_iface.c index 6c18d2a..94c8c05c 100644 --- a/sys/netgraph/ng_iface.c +++ b/sys/netgraph/ng_iface.c @@ -70,9 +70,11 @@ #include <sys/socket.h> #include <sys/syslog.h> #include <sys/libkern.h> +#include <sys/ctype.h> #include <net/if.h> #include <net/if_types.h> +#include <net/if_dl.h> #include <net/bpf.h> #include <net/netisr.h> #include <net/route.h> @@ -166,6 +168,13 @@ static const struct ng_cmdlist ng_iface_cmds[] = { }, { NGM_IFACE_COOKIE, + NGM_IFACE_SET_IFNAME, + "setifname", + &ng_parse_string_type, + NULL + }, + { + NGM_IFACE_COOKIE, NGM_IFACE_POINT2POINT, "point2point", NULL, @@ -608,6 +617,10 @@ ng_iface_rcvmsg(node_p node, item_p item, hook_p lasthook) struct ng_mesg *resp = NULL; int error = 0; struct ng_mesg *msg; + char *new_name; + size_t namelen, onamelen; + struct sockaddr_dl *sdl = NULL; + struct ifaddr *ifa = NULL; NGI_GET_MSG(item, msg); switch (msg->header.typecookie) { @@ -622,6 +635,49 @@ ng_iface_rcvmsg(node_p node, item_p item, hook_p lasthook) strlcpy(resp->data, ifp->if_xname, IFNAMSIZ); break; + case NGM_IFACE_SET_IFNAME: + + new_name = (char *)msg->data; + /* Announce the departure of the interface. */ + //new_name[strlen(new_name)] = '\0'; + + /* Deny request if interface is UP */ + if ((ifp->if_flags & IFF_UP) != 0) { + error = EBUSY; + break; + } + + //rt_ifannouncemsg(ifp, IFAN_DEPARTURE); + EVENTHANDLER_INVOKE(ifnet_departure_event, ifp); + + strlcpy(ifp->if_xname, new_name, sizeof(ifp->if_xname)); + ifa = ifp->if_addr; + IFA_LOCK(ifa); + sdl = (struct sockaddr_dl *)ifa->ifa_addr; + namelen = strlen(new_name) + 1; + onamelen = sdl->sdl_nlen; + /* + * Move the address if needed. This is safe because we + * allocate space for a name of length IFNAMSIZ when we + * create this in if_attach(). + */ + if (namelen != onamelen) { + bcopy(sdl->sdl_data + onamelen, + sdl->sdl_data + namelen, sdl->sdl_alen); + } + bcopy(new_name, sdl->sdl_data, namelen); + sdl->sdl_nlen = namelen; + sdl = (struct sockaddr_dl *)ifa->ifa_netmask; + bzero(sdl->sdl_data, onamelen); + while (namelen != 0) + sdl->sdl_data[--namelen] = 0xff; + IFA_UNLOCK(ifa); + + EVENTHANDLER_INVOKE(ifnet_arrival_event, ifp); + /* Announce the return of the interface. */ + //rt_ifannouncemsg(ifp, IFAN_ARRIVAL); + break; + case NGM_IFACE_POINT2POINT: case NGM_IFACE_BROADCAST: { @@ -699,9 +755,11 @@ ng_iface_rcvmsg(node_p node, item_p item, hook_p lasthook) switch (msg->header.cmd) { case NGM_LINK_IS_UP: ifp->if_drv_flags |= IFF_DRV_RUNNING; + //if_link_state_change(ifp, LINK_STATE_UP); break; case NGM_LINK_IS_DOWN: ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + //if_link_state_change(ifp, LINK_STATE_DOWN); break; default: break; diff --git a/sys/netgraph/ng_iface.h b/sys/netgraph/ng_iface.h index 58fb442..3c843c4 100644 --- a/sys/netgraph/ng_iface.h +++ b/sys/netgraph/ng_iface.h @@ -70,6 +70,7 @@ enum { NGM_IFACE_POINT2POINT, NGM_IFACE_BROADCAST, NGM_IFACE_GET_IFINDEX, + NGM_IFACE_SET_IFNAME, }; #define MTAG_NGIF NGM_IFACE_COOKIE diff --git a/sys/netgraph/ng_message.h b/sys/netgraph/ng_message.h index da531f0..d17ce46 100644 --- a/sys/netgraph/ng_message.h +++ b/sys/netgraph/ng_message.h @@ -138,6 +138,7 @@ enum { NGM_ASCII2BINARY= (13|NGM_READONLY|NGM_HASREPLY), /* (optional) Get/set text config. */ NGM_TEXT_CONFIG = 14, + NGM_ETHER_ATTACH = 15, }; /* |