static void exit_release_resources(int code) { if(tap_fd >= 0) { if_down(); while (wait(NULL) > 0) {} if_release(); while (wait(NULL) > 0) {} } if(ctx != NULL) { if(req_transfer != NULL) { libusb_cancel_transfer(req_transfer); libusb_free_transfer(req_transfer); } libusb_set_pollfd_notifiers(ctx, NULL, NULL, NULL); if(fds != NULL) { free(fds); } if(devh != NULL) { libusb_release_interface(devh, 0); if (kernel_driver_active) libusb_attach_kernel_driver(devh, 0); libusb_unlock_events(ctx); libusb_close(devh); } libusb_exit(ctx); } if(logfile != NULL) { fclose(logfile); } exit(code); }
static int shmif_unclone(struct ifnet *ifp) { struct shmif_sc *sc = ifp->if_softc; shmif_stop(ifp, 1); if_down(ifp); finibackend(sc); mutex_enter(&sc->sc_mtx); sc->sc_dying = true; cv_broadcast(&sc->sc_cv); mutex_exit(&sc->sc_mtx); if (sc->sc_rcvl) kthread_join(sc->sc_rcvl); sc->sc_rcvl = NULL; vmem_xfree(shmif_units, sc->sc_unit+1, 1); ether_ifdetach(ifp); if_detach(ifp); cv_destroy(&sc->sc_cv); mutex_destroy(&sc->sc_mtx); kmem_free(sc, sizeof(*sc)); return 0; }
static void Release( entry *VE ) { int ic, n=0; struct interface idown, *nif; for(nif=&VE->pseudo_if; n<MAX_DEP_IF; nif = &(VE->extra_ifs[n++])) { if(nif->ipaddr.s_addr == 0) break; memcpy(&idown, nif, sizeof(struct interface)); ic = if_down(&idown); if(ic) { const char *em = if_error(); if(em && strlen(em)) { wack_alarm(PRINT, "%d %s", __LINE__, if_error()); } } else { char buffer[16]; snprintf(buffer, 16, inet_ntoa(idown.ipaddr)); wack_alarm(PRINT, "DOWN: %s:%s/%s", idown.ifname,buffer,inet_ntoa(idown.netmask)); } execute_all_user(VE->pseudo_if, VE->extra_ifs, VE->real_if, DLFUNCS_TYPE_ON_DOWN); } My.num_allocated--; }
/* * tunclose - close the device - mark i/f down & delete * routing info */ int tunclose(dev_t dev, int flag, int mode, struct lwp *l) { int s; struct tun_softc *tp; struct ifnet *ifp; s = splnet(); if ((tp = tun_find_zunit(minor(dev))) != NULL) { /* interface was "destroyed" before the close */ seldestroy(&tp->tun_rsel); seldestroy(&tp->tun_wsel); softint_disestablish(tp->tun_osih); softint_disestablish(tp->tun_isih); mutex_destroy(&tp->tun_lock); free(tp, M_DEVBUF); goto out_nolock; } if ((tp = tun_find_unit(dev)) == NULL) goto out_nolock; ifp = &tp->tun_if; tp->tun_flags &= ~TUN_OPEN; tp->tun_pgid = 0; selnotify(&tp->tun_rsel, 0, 0); TUNDEBUG ("%s: closed\n", ifp->if_xname); mutex_exit(&tp->tun_lock); /* * junk all pending output */ IFQ_PURGE(&ifp->if_snd); if (ifp->if_flags & IFF_UP) { if_down(ifp); if (ifp->if_flags & IFF_RUNNING) { /* find internet addresses and delete routes */ struct ifaddr *ifa; IFADDR_FOREACH(ifa, ifp) { #if defined(INET) || defined(INET6) if (ifa->ifa_addr->sa_family == AF_INET || ifa->ifa_addr->sa_family == AF_INET6) { rtinit(ifa, (int)RTM_DELETE, tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0); } #endif } } }
/* * Deallocate a ppp unit. Must be called at splsoftnet or higher. */ void pppdealloc(struct ppp_softc *sc) { struct mbuf *m; if_down(&sc->sc_if); sc->sc_if.if_flags &= ~(IFF_UP|IFF_RUNNING); getmicrotime(&sc->sc_if.if_lastchange); sc->sc_devp = NULL; sc->sc_xfer = NULL; for (;;) { IF_DEQUEUE(&sc->sc_rawq, m); if (m == NULL) break; m_freem(m); } for (;;) { IF_DEQUEUE(&sc->sc_inq, m); if (m == NULL) break; m_freem(m); } for (;;) { IF_DEQUEUE(&sc->sc_fastq, m); if (m == NULL) break; m_freem(m); } while ((m = sc->sc_npqueue) != NULL) { sc->sc_npqueue = m->m_nextpkt; m_freem(m); } #ifdef PPP_COMPRESS ppp_ccp_closed(sc); sc->sc_xc_state = NULL; sc->sc_rc_state = NULL; #endif /* PPP_COMPRESS */ #ifdef PPP_FILTER if (sc->sc_pass_filt.bf_insns != NULL) { kfree(sc->sc_pass_filt.bf_insns, M_DEVBUF); sc->sc_pass_filt.bf_insns = NULL; sc->sc_pass_filt.bf_len = 0; } if (sc->sc_active_filt.bf_insns != NULL) { kfree(sc->sc_active_filt.bf_insns, M_DEVBUF); sc->sc_active_filt.bf_insns = NULL; sc->sc_active_filt.bf_len = 0; } #endif /* PPP_FILTER */ #ifdef VJC if (sc->sc_comp != NULL) { kfree(sc->sc_comp, M_DEVBUF); sc->sc_comp = NULL; } #endif }
/* * Deallocate a ppp unit. Must be called at splsoftnet or higher. */ void pppdealloc(struct ppp_softc *sc) { struct ppp_pkt *pkt; struct mbuf *m; splsoftassert(IPL_SOFTNET); if_down(&sc->sc_if); sc->sc_if.if_flags &= ~(IFF_UP|IFF_RUNNING); sc->sc_devp = NULL; sc->sc_xfer = 0; while ((pkt = ppp_pkt_dequeue(&sc->sc_rawq)) != NULL) ppp_pkt_free(pkt); while ((m = mq_dequeue(&sc->sc_inq)) != NULL) m_freem(m); for (;;) { IF_DEQUEUE(&sc->sc_fastq, m); if (m == NULL) break; m_freem(m); } while ((m = sc->sc_npqueue) != NULL) { sc->sc_npqueue = m->m_nextpkt; m_freem(m); } m_freem(sc->sc_togo); sc->sc_togo = NULL; #ifdef PPP_COMPRESS ppp_ccp_closed(sc); sc->sc_xc_state = NULL; sc->sc_rc_state = NULL; #endif /* PPP_COMPRESS */ #if NBPFILTER > 0 if (sc->sc_pass_filt.bf_insns != 0) { free(sc->sc_pass_filt.bf_insns, M_DEVBUF, 0); sc->sc_pass_filt.bf_insns = 0; sc->sc_pass_filt.bf_len = 0; } if (sc->sc_active_filt.bf_insns != 0) { free(sc->sc_active_filt.bf_insns, M_DEVBUF, 0); sc->sc_active_filt.bf_insns = 0; sc->sc_active_filt.bf_len = 0; } #endif #ifdef VJC if (sc->sc_comp != 0) { free(sc->sc_comp, M_DEVBUF, 0); sc->sc_comp = 0; } #endif }
void usbpf_detach(struct usb_bus *ubus) { struct ifnet *ifp = ubus->ifp; if (ifp != NULL) { bpfdetach(ifp); if_down(ifp); if_detach(ifp); if_free(ifp); } ubus->ifp = NULL; }
void if_refresh (struct interface_FOO *ifp) { if (if_is_operative (ifp)) { if_get_flags (ifp); if (! if_is_operative (ifp)) if_down (ifp); } else { if_get_flags (ifp); if (if_is_operative (ifp)) if_up (ifp); } }
void if_refresh (struct interface *ifp) { if (if_is_up (ifp)) { if_get_flags (ifp); if (! if_is_up (ifp)) if_down (ifp); } else { if_get_flags (ifp); if (if_is_up (ifp)) if_up (ifp); } }
/* * tunclose - close the device - mark i/f down & delete * routing info */ static int tunclose(struct cdev *dev, int foo, int bar, struct thread *td) { struct tun_softc *tp; struct ifnet *ifp; int s; tp = dev->si_drv1; ifp = &tp->tun_if; mtx_lock(&tp->tun_mtx); tp->tun_flags &= ~TUN_OPEN; tp->tun_pid = 0; /* * junk all pending output */ s = splimp(); IFQ_PURGE(&ifp->if_snd); splx(s); mtx_unlock(&tp->tun_mtx); if (ifp->if_flags & IFF_UP) { s = splimp(); if_down(ifp); splx(s); } if (ifp->if_flags & IFF_RUNNING) { struct ifaddr *ifa; s = splimp(); /* find internet addresses and delete routes */ TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) if (ifa->ifa_addr->sa_family == AF_INET) /* Unlocked read. */ rtinit(ifa, (int)RTM_DELETE, tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0); ifp->if_flags &= ~IFF_RUNNING; splx(s); } funsetown(&tp->tun_sigio); selwakeuppri(&tp->tun_rsel, PZERO + 1); TUNDEBUG (ifp, "closed\n"); return (0); }
/* set link_status */ void set_link_status(int link_status) { wd_status.info_updated |= WDS_LINK_STATUS; if (wd_status.link_status == link_status) return; if (wd_status.link_status < 2 && link_status == 2) { if_up(); } if (wd_status.link_status == 2 && link_status < 2) { if_down(); } if (link_status == 1) { first_nego_flag = 1; } wd_status.link_status = link_status; }
/* * When detaching, we do the inverse of what is done in the attach * routine, in reversed order. */ static int tap_detach(device_t self, int flags) { struct tap_softc *sc = device_private(self); struct ifnet *ifp = &sc->sc_ec.ec_if; #if defined(COMPAT_40) || defined(MODULAR) int error; #endif int s; sc->sc_flags |= TAP_GOING; s = splnet(); tap_stop(ifp, 1); if_down(ifp); splx(s); if (sc->sc_sih != NULL) { softint_disestablish(sc->sc_sih); sc->sc_sih = NULL; } #if defined(COMPAT_40) || defined(MODULAR) /* * Destroying a single leaf is a very straightforward operation using * sysctl_destroyv. One should be sure to always end the path with * CTL_EOL. */ if ((error = sysctl_destroyv(NULL, CTL_NET, AF_LINK, tap_node, device_unit(sc->sc_dev), CTL_EOL)) != 0) aprint_error_dev(self, "sysctl_destroyv returned %d, ignoring\n", error); #endif ether_ifdetach(ifp); if_detach(ifp); ifmedia_delete_instance(&sc->sc_im, IFM_INST_ANY); seldestroy(&sc->sc_rsel); mutex_destroy(&sc->sc_rdlock); mutex_destroy(&sc->sc_kqlock); pmf_device_deregister(self); return (0); }
/* Update the flags field of the ifp with the new flag set provided. * Take whatever actions are required for any changes in flags we care * about. * * newflags should be the raw value, as obtained from the OS. */ void if_flags_update (struct interface *ifp, uint64_t newflags) { if_flags_mangle (ifp, &newflags); if (if_is_operative (ifp)) { /* operative -> inoperative? */ ifp->flags = newflags; if (!if_is_operative (ifp)) if_down (ifp); } else { /* inoperative -> operative? */ ifp->flags = newflags; if (if_is_operative (ifp)) if_up (ifp); } }
static int virtif_unclone(struct ifnet *ifp) { struct virtif_sc *sc = ifp->if_softc; int rv; if (ifp->if_flags & IFF_UP) return EBUSY; if ((rv = VIFHYPER_DYING(sc->sc_viu)) != 0) return rv; virtif_stop(ifp, 1); if_down(ifp); VIFHYPER_DESTROY(sc->sc_viu); kmem_free(sc, sizeof(*sc)); ether_ifdetach(ifp); if_detach(ifp); return 0; }
/* * Interface ioctls. */ int ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p) { struct ifnet *ifp; struct ifreq *ifr; int error; switch (cmd) { case SIOCGIFCONF: case OSIOCGIFCONF: return (ifconf(cmd, data)); } ifr = (struct ifreq *)data; ifp = ifunit(ifr->ifr_name); if (ifp == 0) return (ENXIO); switch (cmd) { case SIOCGIFFLAGS: ifr->ifr_flags = ifp->if_flags; break; case SIOCGIFMETRIC: ifr->ifr_metric = ifp->if_metric; break; case SIOCGIFMTU: ifr->ifr_mtu = ifp->if_mtu; break; case SIOCGIFPHYS: ifr->ifr_phys = ifp->if_physical; break; case SIOCSIFFLAGS: error = suser(p->p_ucred, &p->p_acflag); if (error) return (error); if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) { int s = splimp(); if_down(ifp); splx(s); } if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) { int s = splimp(); if_up(ifp); splx(s); } ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | (ifr->ifr_flags &~ IFF_CANTCHANGE); if (ifp->if_ioctl) (void) (*ifp->if_ioctl)(ifp, cmd, data); microtime(&ifp->if_lastchange); break; case SIOCSIFMETRIC: error = suser(p->p_ucred, &p->p_acflag); if (error) return (error); ifp->if_metric = ifr->ifr_metric; microtime(&ifp->if_lastchange); break; case SIOCSIFPHYS: error = suser(p->p_ucred, &p->p_acflag); if (error) return error; if (!ifp->if_ioctl) return EOPNOTSUPP; error = (*ifp->if_ioctl)(ifp, cmd, data); if (error == 0) microtime(&ifp->if_lastchange); return(error); case SIOCSIFMTU: error = suser(p->p_ucred, &p->p_acflag); if (error) return (error); if (ifp->if_ioctl == NULL) return (EOPNOTSUPP); /* * 72 was chosen below because it is the size of a TCP/IP * header (40) + the minimum mss (32). */ if (ifr->ifr_mtu < 72 || ifr->ifr_mtu > 65535L) return (EINVAL); error = (*ifp->if_ioctl)(ifp, cmd, data); if (error == 0) microtime(&ifp->if_lastchange); return(error); case SIOCADDMULTI: case SIOCDELMULTI: error = suser(p->p_ucred, &p->p_acflag); if (error) return (error); if (ifp->if_ioctl == NULL) return (EOPNOTSUPP); error = (*ifp->if_ioctl)(ifp, cmd, data); if (error == 0 ) microtime(&ifp->if_lastchange); return(error); case SIOCSIFMEDIA: error = suser(p->p_ucred, &p->p_acflag); if (error) return (error); if (ifp->if_ioctl == NULL) return (EOPNOTSUPP); error = (*ifp->if_ioctl)(ifp, cmd, data); if (error == 0) microtime(&ifp->if_lastchange); return error; case SIOCGIFMEDIA: if (ifp->if_ioctl == NULL) return (EOPNOTSUPP); return ((*ifp->if_ioctl)(ifp, cmd, data)); default: if (so->so_proto == 0) return (EOPNOTSUPP); #ifndef COMPAT_43 return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, ifp)); #else { int ocmd = cmd; switch (cmd) { case SIOCSIFDSTADDR: case SIOCSIFADDR: case SIOCSIFBRDADDR: case SIOCSIFNETMASK: #if BYTE_ORDER != BIG_ENDIAN if (ifr->ifr_addr.sa_family == 0 && ifr->ifr_addr.sa_len < 16) { ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len; ifr->ifr_addr.sa_len = 16; } #else if (ifr->ifr_addr.sa_len == 0) ifr->ifr_addr.sa_len = 16; #endif break; case OSIOCGIFADDR: cmd = SIOCGIFADDR; break; case OSIOCGIFDSTADDR: cmd = SIOCGIFDSTADDR; break; case OSIOCGIFBRDADDR: cmd = SIOCGIFBRDADDR; break; case OSIOCGIFNETMASK: cmd = SIOCGIFNETMASK; } error = ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, ifp)); switch (ocmd) { case OSIOCGIFADDR: case OSIOCGIFDSTADDR: case OSIOCGIFBRDADDR: case OSIOCGIFNETMASK: *(u_short *)&ifr->ifr_addr = ifr->ifr_addr.sa_family; } return (error); } #endif /* * RTEMS additions for setting/getting `tap' function */ case SIOCSIFTAP: ifp->if_tap = ifr->ifr_tap; return 0; case SIOCGIFTAP: ifr->ifr_tap = ifp->if_tap; return 0; } return (0); }
/* Interface adding function called from interface_list. */ int ifm_read (struct if_msghdr *ifm) { struct interface *ifp; struct sockaddr_dl *sdl = NULL; sdl = (struct sockaddr_dl *)(ifm + 1); /* Use sdl index. */ ifp = if_lookup_by_index (ifm->ifm_index); if (ifp == NULL) { /* Check interface's address.*/ if (! (ifm->ifm_addrs & RTA_IFP)) { zlog_warn ("There must be RTA_IFP address for ifindex %d\n", ifm->ifm_index); return -1; } ifp = if_create (); strncpy (ifp->name, sdl->sdl_data, sdl->sdl_nlen); ifp->ifindex = ifm->ifm_index; ifp->flags = ifm->ifm_flags; #if defined(__bsdi__) if_kvm_get_mtu (ifp); #else if_get_mtu (ifp); #endif /* __bsdi__ */ if_get_metric (ifp); /* Fetch hardware address. */ if (sdl->sdl_family != AF_LINK) { zlog_warn ("sockaddr_dl->sdl_family is not AF_LINK"); return -1; } memcpy (&ifp->sdl, sdl, sizeof (struct sockaddr_dl)); if_add_update (ifp); } else { /* There is a case of promisc, allmulti flag modification. */ if (if_is_up (ifp)) { ifp->flags = ifm->ifm_flags; if (! if_is_up (ifp)) if_down (ifp); } else { ifp->flags = ifm->ifm_flags; if (if_is_up (ifp)) if_up (ifp); } } #ifdef HAVE_NET_RT_IFLIST ifp->stats = ifm->ifm_data; #endif /* HAVE_NET_RT_IFLIST */ if (IS_ZEBRA_DEBUG_KERNEL) zlog_info ("interface %s index %d", ifp->name, ifp->ifindex); return 0; }
int node_netstat_interface_addresses(node_netstat_iface_t** ifaces, node_netstat_iaddress_t** addresses, uint* i_count, uint* a_count) { #ifndef HAVE_IFADDRS_H return -ENOSYS; #else struct ifaddrs *addrs, *entry; node_netstat_iaddress_t* address; /* pointer to list head */ node_netstat_iface_t* iface; /* pointer to list head */ struct rtnl_link_stats *stats; struct sockaddr_ll *sll; if (getifaddrs(&addrs) == -1) { return -errno; } *i_count = 0; *a_count = 0; /* walk through addrs list & count */ for (entry = addrs; entry != NULL; entry = entry->ifa_next) { if (if_down(entry)) { continue; } if (entry->ifa_addr->sa_family == PF_PACKET) { (*i_count)++; } else { (*a_count)++; } } /* allocate mem */ *addresses = malloc(*a_count * sizeof(**addresses)); if (!(*addresses)) { return -ENOMEM; } address = *addresses; /* allocate mem */ *ifaces = malloc(*i_count * sizeof(**ifaces)); if (!(*ifaces)) { free(*addresses); return -ENOMEM; } iface = *ifaces; /* walk through addrs list */ for (entry = addrs; entry != NULL; entry = entry->ifa_next) { if (if_down(entry)) { continue; } if (entry->ifa_addr->sa_family == PF_PACKET) { /* copy name */ iface->name = strdup(entry->ifa_name); /* copy physical address */ sll = (struct sockaddr_ll*)entry->ifa_addr; memcpy(iface->phys_addr, sll->sll_addr, sizeof(iface->phys_addr)); /* loopback flag */ iface->is_internal = !!(entry->ifa_flags & IFF_LOOPBACK); if (entry->ifa_data != NULL) { stats = entry->ifa_data; /* copy stats data */ iface->ibytes = stats->tx_bytes; iface->obytes = stats->rx_bytes; } else { iface->ibytes = 0; iface->obytes = 0; } iface++; } else { /* copy name */ address->name = strdup(entry->ifa_name); /* copy address */ if (entry->ifa_addr->sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6*) entry->ifa_addr); } else if (entry->ifa_addr->sa_family == AF_INET) { address->address.address4 = *((struct sockaddr_in*) entry->ifa_addr); } /* copy netmask */ if (entry->ifa_netmask->sa_family == AF_INET6) { address->netmask.netmask6 = *((struct sockaddr_in6*) entry->ifa_netmask); } else if (entry->ifa_netmask->sa_family == AF_INET) { address->netmask.netmask4 = *((struct sockaddr_in*) entry->ifa_netmask); } /* loopback flag */ address->is_internal = !!(entry->ifa_flags & IFF_LOOPBACK); address++; } } freeifaddrs(addrs); return 0; #endif }
static int netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h) { int len; struct ifinfomsg *ifi; struct rtattr *tb[IFLA_MAX + 1]; struct interface *ifp; char *name; ifi = NLMSG_DATA (h); if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK)) { /* If this is not link add/delete message so print warning. */ zlog_warn ("netlink_link_change: wrong kernel message %d\n", h->nlmsg_type); return 0; } len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg)); if (len < 0) return -1; /* Looking up interface name. */ memset (tb, 0, sizeof tb); netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len); #ifdef IFLA_WIRELESS /* check for wireless messages to ignore */ if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0)) { if (IS_DEBUG_HA(kroute, KROUTE)) zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__); return 0; } #endif /* IFLA_WIRELESS */ if (tb[IFLA_IFNAME] == NULL) return -1; name = (char *) RTA_DATA (tb[IFLA_IFNAME]); /* Add interface. */ if (h->nlmsg_type == RTM_NEWLINK) { ifp = if_lookup_by_name (name); if (ifp == NULL || !CHECK_FLAG (ifp->status, KROUTE_INTERFACE_ACTIVE)) { if (ifp == NULL) ifp = if_get_by_name (name); set_ifindex(ifp, ifi->ifi_index); ifp->flags = ifi->ifi_flags & 0x0000fffff; ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]); ifp->metric = 1; netlink_interface_update_hw_addr (tb, ifp); /* If new link is added. */ if_add_update (ifp); } else { /* Interface status change. */ set_ifindex(ifp, ifi->ifi_index); ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]); ifp->metric = 1; netlink_interface_update_hw_addr (tb, ifp); if (if_is_operative (ifp)) { ifp->flags = ifi->ifi_flags & 0x0000fffff; if (!if_is_operative (ifp)) if_down (ifp); else /* Must notify client daemons of new interface status. */ kroute_interface_up_update (ifp); } else { ifp->flags = ifi->ifi_flags & 0x0000fffff; if (if_is_operative (ifp)) if_up (ifp); } } } else { /* RTM_DELLINK. */ ifp = if_lookup_by_name (name); if (ifp == NULL) { zlog (NULL, LOG_WARNING, "interface %s is deleted but can't find", name); return 0; } if_delete_update (ifp); } return 0; }
int netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h) { int len; struct ifinfomsg *ifi; struct rtattr *tb [IFLA_MAX + 1]; struct interface *ifp; char *name; ifi = NLMSG_DATA (h); if (! (h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK)) { /* If this is not link add/delete message so print warning. */ zlog_warn ("netlink_link_change: wrong kernel message %d\n", h->nlmsg_type); return 0; } len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg)); if (len < 0) return -1; /* Looking up interface name. */ memset (tb, 0, sizeof tb); netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len); if (tb[IFLA_IFNAME] == NULL) return -1; name = (char *)RTA_DATA(tb[IFLA_IFNAME]); /* Add interface. */ if (h->nlmsg_type == RTM_NEWLINK) { ifp = if_lookup_by_name (name); if (ifp == NULL || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) { if (ifp == NULL) ifp = if_get_by_name (name); ifp->ifindex = ifi->ifi_index; ifp->flags = ifi->ifi_flags & 0x0000fffff; ifp->mtu = *(int *)RTA_DATA (tb[IFLA_MTU]); ifp->metric = 1; /* If new link is added. */ if_add_update(ifp); } else { /* Interface status change. */ ifp->ifindex = ifi->ifi_index; ifp->mtu = *(int *)RTA_DATA (tb[IFLA_MTU]); ifp->metric = 1; if (if_is_up (ifp)) { ifp->flags = ifi->ifi_flags & 0x0000fffff; if (! if_is_up (ifp)) if_down (ifp); } else { ifp->flags = ifi->ifi_flags & 0x0000fffff; if (if_is_up (ifp)) if_up (ifp); } } } else { /* RTM_DELLINK. */ ifp = if_lookup_by_name (name); if (ifp == NULL) { zlog (NULL, LOG_WARNING, "interface %s is deleted but can't find", ifp->name); return 0; } if_delete_update (ifp); } return 0; }
void logger_shutdown (void) { if_down(g_sid); }
static int sfxge_if_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data) { struct sfxge_softc *sc; struct ifreq *ifr; int error; ifr = (struct ifreq *)data; sc = ifp->if_softc; error = 0; switch (command) { case SIOCSIFFLAGS: sx_xlock(&sc->softc_lock); if (ifp->if_flags & IFF_UP) { if (ifp->if_drv_flags & IFF_DRV_RUNNING) { if ((ifp->if_flags ^ sc->if_flags) & (IFF_PROMISC | IFF_ALLMULTI)) { sfxge_mac_filter_set(sc); } } else sfxge_start(sc); } else if (ifp->if_drv_flags & IFF_DRV_RUNNING) sfxge_stop(sc); sc->if_flags = ifp->if_flags; sx_xunlock(&sc->softc_lock); break; case SIOCSIFMTU: if (ifr->ifr_mtu == ifp->if_mtu) { /* Nothing to do */ error = 0; } else if (ifr->ifr_mtu > SFXGE_MAX_MTU) { error = EINVAL; } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { ifp->if_mtu = ifr->ifr_mtu; error = 0; } else { /* Restart required */ sx_xlock(&sc->softc_lock); sfxge_stop(sc); ifp->if_mtu = ifr->ifr_mtu; error = sfxge_start(sc); sx_xunlock(&sc->softc_lock); if (error) { ifp->if_flags &= ~IFF_UP; ifp->if_drv_flags &= ~IFF_DRV_RUNNING; if_down(ifp); } } break; case SIOCADDMULTI: case SIOCDELMULTI: if (ifp->if_drv_flags & IFF_DRV_RUNNING) sfxge_mac_filter_set(sc); break; case SIOCSIFCAP: sx_xlock(&sc->softc_lock); /* * The networking core already rejects attempts to * enable capabilities we don't have. We still have * to reject attempts to disable capabilities that we * can't (yet) disable. */ if (~ifr->ifr_reqcap & SFXGE_CAP_FIXED) { error = EINVAL; sx_xunlock(&sc->softc_lock); break; } ifp->if_capenable = ifr->ifr_reqcap; if (ifp->if_capenable & IFCAP_TXCSUM) ifp->if_hwassist |= (CSUM_IP | CSUM_TCP | CSUM_UDP); else ifp->if_hwassist &= ~(CSUM_IP | CSUM_TCP | CSUM_UDP); if (ifp->if_capenable & IFCAP_TSO) ifp->if_hwassist |= CSUM_TSO; else ifp->if_hwassist &= ~CSUM_TSO; sx_xunlock(&sc->softc_lock); break; case SIOCSIFMEDIA: case SIOCGIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &sc->media, command); break; default: error = ether_ioctl(ifp, command, data); } return (error); }
int main (int argc, char *argv[]) { int A,B,C,D, i, ic; struct interface req, myips[300]; int state; #ifdef WIN32 WSADATA wsadata; WSAStartup(WINSOCK_VERSION, &wsadata); #endif i=1; if(argc < 2) goto usage_error; if(argv[i][0] != '-') goto usage_error; switch(argv[i++][1]) { case 'r': state=ARPLIST; break; case 'l': state=LIST; break; case 'a': state=ADD; strcpy(req.ifname, argv[i++]); sscanf(argv[i++], "%d.%d.%d.%d", &A,&B,&C,&D); req.ipaddr.s_addr = htonl((A << 24) | (B << 16) | (C << 8) | D); sscanf(argv[i++], "%d.%d.%d.%d", &A,&B,&C,&D); req.bcast.s_addr = htonl((A << 24) | (B << 16) | (C << 8) | D); sscanf(argv[i++], "%d.%d.%d.%d", &A,&B,&C,&D); req.netmask.s_addr = htonl((A << 24) | (B << 16) | (C << 8) | D); break; case 'd': state=DELETE; sscanf(argv[i++], "%d.%d.%d.%d", &A,&B,&C,&D); req.ifname[0] = '\0'; req.ipaddr.s_addr = htonl((A << 24) | (B << 16) | (C << 8) | D); break; case 's': state=SPOOF; strcpy(req.ifname, argv[i++]); sscanf(argv[i++], "%d.%d.%d.%d", &A,&B,&C,&D); req.ipaddr.s_addr = htonl((A << 24) | (B << 16) | (C << 8) | D); sscanf(argv[i++], "%d.%d.%d.%d", &A,&B,&C,&D); req.bcast.s_addr = htonl((A << 24) | (B << 16) | (C << 8) | D); break; usage_error: default: fprintf(stderr, "%s:\n\tUsage:\n\t\t-l\t\t\t\t\tlist interfaces\n\t\t-a <interface> <ip> <bcast> <netmask>\tAdd this VIP\n\t\t-d <IP>\t\t\t\t\tDelete this VIP\n\t\t-s interface VIP destinationIP\n", argv[0]); exit(-1); } if_initialize(); if(state&ARPLIST) { arp_entry *ad, *ac; fprintf(stderr, "Sampling and printing local arp-cache\n"); sample_arp_cache(); sample_arp_cache(); ac = ad = fetch_shared_arp_cache(); while(ad && ad->ip) { struct in_addr iad; iad.s_addr = ad->ip; fprintf(stderr, "\t%s\n", inet_ntoa(iad)); ad++; } free(ac); } if(state&ADD) { ic = if_up(&req); if(ic) { perror("ioctl"); fprintf(stderr, "%s\n", if_error()); } else { fprintf(stderr, "if_up: %s\t%s", req.ifname, inet_ntoa(req.ipaddr)); fprintf(stderr, "\t%s", inet_ntoa(req.bcast)); fprintf(stderr, "\t%s\n", inet_ntoa(req.netmask)); } } if(state&DELETE) { ic = if_down(&req); if(ic) fprintf(stderr, "%s\n", if_error()); else { fprintf(stderr, "if_down: %s\t%s", req.ifname, inet_ntoa(req.ipaddr)); fprintf(stderr, "\t%s", inet_ntoa(req.bcast)); fprintf(stderr, "\t%s\n", inet_ntoa(req.netmask)); } } if(state&SPOOF) { ic = if_send_spoof_request(req.ifname, req.ipaddr.s_addr, req.bcast.s_addr, NULL, 5, 0); if(ic) fprintf(stderr, "%s\n", if_error()); else { fprintf(stderr, "if_spoofed: %s\t%s\n",req.ifname, inet_ntoa(req.ipaddr)); } } if(state) { ic = if_list_ips(myips, 300); fprintf(stderr, "Found %d IPs:\n", ic); for(i=0; i<ic; i++) { fprintf(stderr, "%s\t[%02x:%02x:%02x:%02x:%02x:%02x]", myips[i].ifname, myips[i].mac[0], myips[i].mac[1], myips[i].mac[2], myips[i].mac[3], myips[i].mac[4], myips[i].mac[5]); fprintf(stderr, "\t%s", inet_ntoa(myips[i].ipaddr)); fprintf(stderr, "\t%s", inet_ntoa(myips[i].bcast)); fprintf(stderr, "\t%s\n", inet_ntoa(myips[i].netmask)); } } return 0; }
int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) { int len; struct ifinfomsg *ifi; struct rtattr *tb[IFLA_MAX + 1]; struct rtattr *linkinfo[IFLA_MAX + 1]; struct interface *ifp; char *name = NULL; char *kind = NULL; char *desc = NULL; char *slave_kind = NULL; struct zebra_ns *zns; vrf_id_t vrf_id = VRF_DEFAULT; zebra_iftype_t zif_type = ZEBRA_IF_OTHER; zebra_slave_iftype_t zif_slave_type = ZEBRA_IF_SLAVE_NONE; ifindex_t bridge_ifindex = IFINDEX_INTERNAL; ifindex_t link_ifindex = IFINDEX_INTERNAL; zns = zebra_ns_lookup(ns_id); ifi = NLMSG_DATA(h); /* assume if not default zns, then new VRF */ if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK)) { /* If this is not link add/delete message so print warning. */ zlog_warn("netlink_link_change: wrong kernel message %d", h->nlmsg_type); return 0; } if (!(ifi->ifi_family == AF_UNSPEC || ifi->ifi_family == AF_BRIDGE || ifi->ifi_family == AF_INET6)) { zlog_warn( "Invalid address family: %u received from kernel link change: %u", ifi->ifi_family, h->nlmsg_type); return 0; } len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg)); if (len < 0) { zlog_err("%s: Message received from netlink is of a broken size %d %zu", __PRETTY_FUNCTION__, h->nlmsg_len, (size_t)NLMSG_LENGTH(sizeof(struct ifinfomsg))); return -1; } /* We are interested in some AF_BRIDGE notifications. */ if (ifi->ifi_family == AF_BRIDGE) return netlink_bridge_interface(h, len, ns_id, startup); /* Looking up interface name. */ memset(tb, 0, sizeof tb); memset(linkinfo, 0, sizeof linkinfo); netlink_parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); /* check for wireless messages to ignore */ if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0)) { if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug("%s: ignoring IFLA_WIRELESS message", __func__); return 0; } if (tb[IFLA_IFNAME] == NULL) return -1; name = (char *)RTA_DATA(tb[IFLA_IFNAME]); if (tb[IFLA_LINKINFO]) { parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]); if (linkinfo[IFLA_INFO_KIND]) kind = RTA_DATA(linkinfo[IFLA_INFO_KIND]); if (linkinfo[IFLA_INFO_SLAVE_KIND]) slave_kind = RTA_DATA(linkinfo[IFLA_INFO_SLAVE_KIND]); netlink_determine_zebra_iftype(kind, &zif_type); } /* If linking to another interface, note it. */ if (tb[IFLA_LINK]) link_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_LINK]); if (tb[IFLA_IFALIAS]) { desc = (char *)RTA_DATA(tb[IFLA_IFALIAS]); } /* If VRF, create or update the VRF structure itself. */ if (zif_type == ZEBRA_IF_VRF && !vrf_is_backend_netns()) { netlink_vrf_change(h, tb[IFLA_LINKINFO], name); vrf_id = (vrf_id_t)ifi->ifi_index; } /* See if interface is present. */ ifp = if_lookup_by_name_per_ns(zns, name); if (ifp) { if (ifp->desc) XFREE(MTYPE_TMP, ifp->desc); if (desc) ifp->desc = XSTRDUP(MTYPE_TMP, desc); } if (h->nlmsg_type == RTM_NEWLINK) { if (tb[IFLA_MASTER]) { if (slave_kind && (strcmp(slave_kind, "vrf") == 0) && !vrf_is_backend_netns()) { zif_slave_type = ZEBRA_IF_SLAVE_VRF; vrf_id = *(uint32_t *)RTA_DATA(tb[IFLA_MASTER]); } else if (slave_kind && (strcmp(slave_kind, "bridge") == 0)) { zif_slave_type = ZEBRA_IF_SLAVE_BRIDGE; bridge_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_MASTER]); } else zif_slave_type = ZEBRA_IF_SLAVE_OTHER; } if (vrf_is_backend_netns()) vrf_id = (vrf_id_t)ns_id; if (ifp == NULL || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { /* Add interface notification from kernel */ if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( "RTM_NEWLINK ADD for %s(%u) vrf_id %u type %d " "sl_type %d master %u flags 0x%x", name, ifi->ifi_index, vrf_id, zif_type, zif_slave_type, bridge_ifindex, ifi->ifi_flags); if (ifp == NULL) { /* unknown interface */ ifp = if_get_by_name(name, vrf_id, 0); } else { /* pre-configured interface, learnt now */ if (ifp->vrf_id != vrf_id) if_update_to_new_vrf(ifp, vrf_id); } /* Update interface information. */ set_ifindex(ifp, ifi->ifi_index, zns); ifp->flags = ifi->ifi_flags & 0x0000fffff; if (!tb[IFLA_MTU]) { zlog_warn( "RTM_NEWLINK for interface %s(%u) without MTU set", name, ifi->ifi_index); return 0; } ifp->mtu6 = ifp->mtu = *(int *)RTA_DATA(tb[IFLA_MTU]); ifp->metric = 0; ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN; /* Set interface type */ zebra_if_set_ziftype(ifp, zif_type, zif_slave_type); if (IS_ZEBRA_IF_VRF(ifp)) SET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK); /* Update link. */ zebra_if_update_link(ifp, link_ifindex); netlink_interface_update_hw_addr(tb, ifp); /* Inform clients, install any configured addresses. */ if_add_update(ifp); /* Extract and save L2 interface information, take * additional actions. */ netlink_interface_update_l2info( ifp, linkinfo[IFLA_INFO_DATA], 1); if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) zebra_l2if_update_bridge_slave(ifp, bridge_ifindex); if_netlink_check_ifp_instance_consistency(RTM_NEWLINK, ifp, ns_id); } else if (ifp->vrf_id != vrf_id) { /* VRF change for an interface. */ if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( "RTM_NEWLINK vrf-change for %s(%u) " "vrf_id %u -> %u flags 0x%x", name, ifp->ifindex, ifp->vrf_id, vrf_id, ifi->ifi_flags); if_handle_vrf_change(ifp, vrf_id); } else { int was_bridge_slave; /* Interface update. */ if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( "RTM_NEWLINK update for %s(%u) " "sl_type %d master %u flags 0x%x", name, ifp->ifindex, zif_slave_type, bridge_ifindex, ifi->ifi_flags); set_ifindex(ifp, ifi->ifi_index, zns); if (!tb[IFLA_MTU]) { zlog_warn( "RTM_NEWLINK for interface %s(%u) without MTU set", name, ifi->ifi_index); return 0; } ifp->mtu6 = ifp->mtu = *(int *)RTA_DATA(tb[IFLA_MTU]); ifp->metric = 0; /* Update interface type - NOTE: Only slave_type can * change. */ was_bridge_slave = IS_ZEBRA_IF_BRIDGE_SLAVE(ifp); zebra_if_set_ziftype(ifp, zif_type, zif_slave_type); netlink_interface_update_hw_addr(tb, ifp); if (if_is_no_ptm_operative(ifp)) { ifp->flags = ifi->ifi_flags & 0x0000fffff; if (!if_is_no_ptm_operative(ifp)) { if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( "Intf %s(%u) has gone DOWN", name, ifp->ifindex); if_down(ifp); } else if (if_is_operative(ifp)) { /* Must notify client daemons of new * interface status. */ if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( "Intf %s(%u) PTM up, notifying clients", name, ifp->ifindex); zebra_interface_up_update(ifp); } } else { ifp->flags = ifi->ifi_flags & 0x0000fffff; if (if_is_operative(ifp)) { if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( "Intf %s(%u) has come UP", name, ifp->ifindex); if_up(ifp); } } /* Extract and save L2 interface information, take * additional actions. */ netlink_interface_update_l2info( ifp, linkinfo[IFLA_INFO_DATA], 0); if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) || was_bridge_slave) zebra_l2if_update_bridge_slave(ifp, bridge_ifindex); if_netlink_check_ifp_instance_consistency(RTM_NEWLINK, ifp, ns_id); } } else { /* Delete interface notification from kernel */ if (ifp == NULL) { zlog_warn("RTM_DELLINK for unknown interface %s(%u)", name, ifi->ifi_index); return 0; } if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug("RTM_DELLINK for %s(%u)", name, ifp->ifindex); UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK); /* Special handling for bridge or VxLAN interfaces. */ if (IS_ZEBRA_IF_BRIDGE(ifp)) zebra_l2_bridge_del(ifp); else if (IS_ZEBRA_IF_VXLAN(ifp)) zebra_l2_vxlanif_del(ifp); if (!IS_ZEBRA_IF_VRF(ifp)) if_delete_update(ifp); if_netlink_check_ifp_instance_consistency(RTM_DELLINK, ifp, ns_id); } return 0; }
extern int reboot_main(int argc, char **argv) { char *delay; /* delay in seconds before rebooting */ unsigned long opt; int fw_upgrade = 0; #if defined(TCSUPPORT_START_TRAP) || defined(TCSUPPORT_SYSLOG_ENHANCE) int count = 0; #endif if((opt = bb_getopt_ulflags(argc, argv, "d:u", &delay)) > 0) { if (opt & 0x1) sleep(atoi(delay)); if (opt & 0x2) fw_upgrade = 1; } system("killall -9 monitorcfgmgr"); //Andy Chiu, 2015/03/18. stop monitorcfgmgr before stop cfg_manager if (fw_upgrade) { system("killall -9 cfg_manager"); } else { system("killall -SIGTERM cfg_manager"); //Andy Chiu, 2015/05/12. send SIGTERM to cfg_manager first and make sure it /* wait cfg_manager done */ while (!quit_signal() && count++ < 10) sleep(1); } #ifdef TCSUPPORT_SYSLOG_ENHANCE count = 0; system("killall syslogd"); /* wait syslogd storing system log */ while (!syslogd_quit_signal() && count++ < 10) sleep(1); #endif #if defined(TCSUPPORT_CPU_MT7510) || defined(TCSUPPORT_CPU_MT7520) #if defined(MT7592) if_down("wds0"); if_down("wds1"); if_down("wds2"); if_down("wds3"); if_down("ra0"); if_down("ra1"); if_down("ra2"); if_down("ra3"); syscall(__NR_delete_module, "mt7603eap", O_NONBLOCK|O_EXCL); #endif #if defined(MT7612E) if_down("wdsi0"); if_down("wdsi1"); if_down("wdsi2"); if_down("wdsi3"); if_down("rai0"); if_down("rai1"); if_down("rai2"); if_down("rai3"); syscall(__NR_delete_module, "mt7662e_ap", O_NONBLOCK|O_EXCL); #endif #if defined(MT7610E) if_down("wdsi0"); if_down("wdsi1"); if_down("wdsi2"); if_down("wdsi3"); if_down("rai0"); if_down("rai1"); if_down("rai2"); if_down("rai3"); syscall(__NR_delete_module, "mt7610e_ap", O_NONBLOCK|O_EXCL); #endif #endif #ifndef CONFIG_INIT #ifndef RB_AUTOBOOT #define RB_AUTOBOOT 0x01234567 #endif return(bb_shutdown_system(RB_AUTOBOOT)); #else return kill_init(SIGTERM); #endif }