int altqioctl(dev_t dev, ioctlcmd_t cmd, void *addr, int flag, struct lwp *l) { int unit = minor(dev); if (unit == 0) { struct ifnet *ifp; struct altqreq *typereq; struct tbrreq *tbrreq; int error; switch (cmd) { case ALTQGTYPE: case ALTQTBRGET: break; default: #if (__FreeBSD_version > 400000) if ((error = suser(p)) != 0) return (error); #else if ((error = kauth_authorize_network(l->l_cred, KAUTH_NETWORK_ALTQ, KAUTH_REQ_NETWORK_ALTQ_CONF, NULL, NULL, NULL)) != 0) return (error); #endif break; } switch (cmd) { case ALTQGTYPE: typereq = (struct altqreq *)addr; if ((ifp = ifunit(typereq->ifname)) == NULL) return (EINVAL); typereq->arg = (u_long)ifp->if_snd.altq_type; return (0); case ALTQTBRSET: tbrreq = (struct tbrreq *)addr; if ((ifp = ifunit(tbrreq->ifname)) == NULL) return (EINVAL); return tbr_set(&ifp->if_snd, &tbrreq->tb_prof); case ALTQTBRGET: tbrreq = (struct tbrreq *)addr; if ((ifp = ifunit(tbrreq->ifname)) == NULL) return (EINVAL); return tbr_get(&ifp->if_snd, &tbrreq->tb_prof); default: return (EINVAL); } } if (unit < naltqsw) return (*altqsw[unit].d_ioctl)(dev, cmd, addr, flag, l); return ENXIO; }
int net_clone_bridge_init(char *l_inf, char *e_inf) { #ifdef MAT mat_lfp = ifunit(l_inf); mat_efp = ifunit(e_inf); ip2mac_init(); //diag_printf("net_clone_bridge_init: net_clone_mac_addr=%s\n", ether_ntoa(net_clone_mac_addr) ); diag_printf("cloneing bridge init, local if=%x, ext if=%x\n", mat_lfp, mat_efp ); #endif return 0; }
int cbq_add_altq(struct pf_altq *a) { cbq_state_t *cbqp; struct ifnet *ifp; ifnet_lock(); if ((ifp = ifunit(a->ifname)) == NULL) { ifnet_unlock(); return (EINVAL); } if (!ifq_is_ready(&ifp->if_snd)) { ifnet_unlock(); return (ENODEV); } /* allocate and initialize cbq_state_t */ cbqp = kmalloc(sizeof(*cbqp), M_ALTQ, M_WAITOK | M_ZERO); callout_init(&cbqp->cbq_callout); cbqp->cbq_qlen = 0; cbqp->ifnp.ifq_ = &ifp->if_snd; /* keep the ifq */ ifq_purge_all(&ifp->if_snd); ifnet_unlock(); /* keep the state in pf_altq */ a->altq_disc = cbqp; return (0); }
bool vboxNetFltOsMaybeRediscovered(PVBOXNETFLTINS pThis) { struct ifnet *ifp, *ifp0; ifp = ASMAtomicUoReadPtrT(&pThis->u.s.ifp, struct ifnet *); VBOXCURVNET_SET(ifp->if_vnet); /* * Attempt to check if the interface is still there and re-initialize if * something has changed. */ ifp0 = ifunit(pThis->szName); if (ifp != ifp0) { ASMAtomicUoWriteBool(&pThis->fDisconnectedFromHost, true); ng_rmnode_self(pThis->u.s.node); pThis->u.s.node = NULL; } if (ifp0 != NULL) { vboxNetFltOsDeleteInstance(pThis); vboxNetFltOsInitInstance(pThis, NULL); } VBOXCURVNET_RESTORE(); return !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost); }
int cbq_add_altq(struct pf_altq *a) { cbq_state_t *cbqp; struct ifnet *ifp; if ((ifp = ifunit(a->ifname)) == NULL) return (EINVAL); if (!ALTQ_IS_READY(&ifp->if_snd)) return (ENODEV); /* allocate and initialize cbq_state_t */ cbqp = malloc(sizeof(cbq_state_t), M_DEVBUF, M_WAITOK|M_ZERO); if (cbqp == NULL) return (ENOMEM); (void)memset(cbqp, 0, sizeof(cbq_state_t)); CALLOUT_INIT(&cbqp->cbq_callout); cbqp->cbq_qlen = 0; cbqp->ifnp.ifq_ = &ifp->if_snd; /* keep the ifq */ /* keep the state in pf_altq */ a->altq_disc = cbqp; return (0); }
int afmioctl(dev_t dev, ioctlcmd_t cmd, void *addr, int flag, struct lwp *l) { int error = 0; struct atm_flowmap *flowmap; struct ifnet *ifp; /* check cmd for superuser only */ switch (cmd) { case AFM_GETFMAP: break; default: #if (__FreeBSD_version > 400000) error = suser(p); #else error = kauth_authorize_network(l->l_cred, KAUTH_NETWORK_ALTQ, KAUTH_REQ_NETWORK_ALTQ_AFMAP, NULL, NULL, NULL); #endif if (error) return (error); break; } /* lookup interface */ flowmap = (struct atm_flowmap *)addr; flowmap->af_ifname[IFNAMSIZ-1] = '\0'; ifp = ifunit(flowmap->af_ifname); if (ifp == NULL || (ifp->if_flags & IFF_RUNNING) == 0) error = ENXIO; else error = ifp->if_ioctl(ifp, cmd, addr); return error; }
int hfsc_add_altq(struct pf_altq *a) { struct hfsc_if *hif; struct ifnet *ifp; if ((ifp = ifunit(a->ifname)) == NULL) return (EINVAL); if (!ALTQ_IS_READY(&ifp->if_snd)) return (ENODEV); MALLOC(hif, struct hfsc_if *, sizeof(struct hfsc_if), M_DEVBUF, M_WAITOK); if (hif == NULL) return (ENOMEM); bzero(hif, sizeof(struct hfsc_if)); hif->hif_eligible = ellist_alloc(); if (hif->hif_eligible == NULL) { FREE(hif, M_DEVBUF); return (ENOMEM); } hif->hif_ifq = &ifp->if_snd; /* keep the state in pf_altq */ a->altq_disc = hif; return (0); }
int priq_add_altq(struct pf_altq *a) { struct priq_if *pif; struct ifnet *ifp; if ((ifp = ifunit(a->ifname)) == NULL) return (EINVAL); if (!ALTQ_IS_READY(&ifp->if_snd)) return (ENODEV); pif = malloc(sizeof(struct priq_if), M_DEVBUF, M_WAITOK); if (pif == NULL) return (ENOMEM); bzero(pif, sizeof(struct priq_if)); pif->pif_bandwidth = a->ifbandwidth; pif->pif_maxpri = -1; pif->pif_ifq = &ifp->if_snd; /* keep the state in pf_altq */ a->altq_disc = pif; return (0); }
int vboxNetFltOsInitInstance(PVBOXNETFLTINS pThis, void *pvContext) { char nam[NG_NODESIZ]; struct ifnet *ifp; node_p node; RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; VBOXCURVNET_SET_FROM_UCRED(); NOREF(pvContext); ifp = ifunit(pThis->szName); if (ifp == NULL) return VERR_INTNET_FLT_IF_NOT_FOUND; /* Create a new netgraph node for this instance */ if (ng_make_node_common(&ng_vboxnetflt_typestruct, &node) != 0) return VERR_INTERNAL_ERROR; RTSpinlockAcquireNoInts(pThis->hSpinlock, &Tmp); ASMAtomicUoWritePtr(&pThis->u.s.ifp, ifp); pThis->u.s.node = node; bcopy(IF_LLADDR(ifp), &pThis->u.s.MacAddr, ETHER_ADDR_LEN); ASMAtomicUoWriteBool(&pThis->fDisconnectedFromHost, false); /* Initialize deferred input queue */ bzero(&pThis->u.s.inq, sizeof(struct ifqueue)); mtx_init(&pThis->u.s.inq.ifq_mtx, "vboxnetflt inq", NULL, MTX_SPIN); TASK_INIT(&pThis->u.s.tskin, 0, vboxNetFltFreeBSDinput, pThis); /* Initialize deferred output queue */ bzero(&pThis->u.s.outq, sizeof(struct ifqueue)); mtx_init(&pThis->u.s.outq.ifq_mtx, "vboxnetflt outq", NULL, MTX_SPIN); TASK_INIT(&pThis->u.s.tskout, 0, vboxNetFltFreeBSDoutput, pThis); RTSpinlockReleaseNoInts(pThis->hSpinlock, &Tmp); NG_NODE_SET_PRIVATE(node, pThis); /* Attempt to name it vboxnetflt_<ifname> */ snprintf(nam, NG_NODESIZ, "vboxnetflt_%s", pThis->szName); ng_name_node(node, nam); /* Report MAC address, promiscuous mode and GSO capabilities. */ /** @todo keep these reports up to date, either by polling for changes or * intercept some control flow if possible. */ if (vboxNetFltTryRetainBusyNotDisconnected(pThis)) { Assert(pThis->pSwitchPort); pThis->pSwitchPort->pfnReportMacAddress(pThis->pSwitchPort, &pThis->u.s.MacAddr); pThis->pSwitchPort->pfnReportPromiscuousMode(pThis->pSwitchPort, vboxNetFltFreeBsdIsPromiscuous(pThis)); pThis->pSwitchPort->pfnReportGsoCapabilities(pThis->pSwitchPort, 0, INTNETTRUNKDIR_WIRE | INTNETTRUNKDIR_HOST); pThis->pSwitchPort->pfnReportNoPreemptDsts(pThis->pSwitchPort, 0 /* none */); vboxNetFltRelease(pThis, true /*fBusy*/); } VBOXCURVNET_RESTORE(); return VINF_SUCCESS; }
static int wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params) { struct ieee80211_clone_params cp; struct ieee80211vap *vap; struct ieee80211com *ic; struct ifnet *ifp; int error; error = copyin(params, &cp, sizeof(cp)); if (error) return error; ifp = ifunit(cp.icp_parent); if (ifp == NULL) return ENXIO; /* XXX move printfs to DIAGNOSTIC before release */ if (ifp->if_type != IFT_IEEE80211) { if_printf(ifp, "%s: reject, not an 802.11 device\n", __func__); return ENXIO; } if (cp.icp_opmode >= IEEE80211_OPMODE_MAX) { if_printf(ifp, "%s: invalid opmode %d\n", __func__, cp.icp_opmode); return EINVAL; } ic = ifp->if_l2com; if ((ic->ic_caps & ieee80211_opcap[cp.icp_opmode]) == 0) { if_printf(ifp, "%s mode not supported\n", ieee80211_opmode_name[cp.icp_opmode]); return EOPNOTSUPP; } if ((cp.icp_flags & IEEE80211_CLONE_TDMA) && #ifdef IEEE80211_SUPPORT_TDMA (ic->ic_caps & IEEE80211_C_TDMA) == 0 #else (1) #endif ) { if_printf(ifp, "TDMA not supported\n"); return EOPNOTSUPP; } #if __FreeBSD_version >= 1000020 vap = ic->ic_vap_create(ic, wlanname, unit, cp.icp_opmode, cp.icp_flags, cp.icp_bssid, cp.icp_flags & IEEE80211_CLONE_MACADDR ? cp.icp_macaddr : (const uint8_t *)IF_LLADDR(ifp)); #else vap = ic->ic_vap_create(ic, ifc->ifc_name, unit, cp.icp_opmode, cp.icp_flags, cp.icp_bssid, cp.icp_flags & IEEE80211_CLONE_MACADDR ? cp.icp_macaddr : (const uint8_t *)IF_LLADDR(ifp)); #endif return (vap == NULL ? EIO : 0); }
int netarp_del(struct in_addr *host, char *ifname) { struct ifnet *ifp = NULL; if (ifname != NULL) ifp = ifunit(ifname); return netarpcmd(SIOCDARP, host->s_addr, NULL, NULL, ifp); }
int netarp_add(struct in_addr *host, char *macs, char *ifname, int inflag) { struct ifnet *ifp = NULL; int flags = inflag; if (ifname != NULL) ifp = ifunit(ifname); return netarpcmd(SIOCSARP, host->s_addr, macs, &flags, ifp); }
int init_interface(const char *ifname, struct interface **ifacep) { struct ifnet *ifp; struct ifreq ifr; struct interface *iface = NULL; int error; ifp = ifunit(ifname); if (!ifp) return EXDEV; memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if ((error = ifioctl(socket_afnet, SIOCGIFFLAGS, &ifr, curlwp)) != 0) goto eexit; iface = kmem_zalloc(sizeof(*iface), KM_SLEEP); strlcpy(iface->name, ifname, sizeof(iface->name)); iface->ifp = ifp; iface->flags = ifr.ifr_flags; /* We reserve the 100 range for virtual interfaces, if and when * we can work them out. */ iface->metric = 200 + iface->ifp->if_index; if (getifssid(ifname, iface->ssid) == 0) { iface->wireless = 1; iface->metric += 100; } if (ifioctl(socket_afnet, SIOCGIFMTU, &ifr, curlwp) != 0) goto eexit; /* Ensure that the MTU is big enough for DHCP */ if (ifr.ifr_mtu < MTU_MIN) { ifr.ifr_mtu = MTU_MIN; strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if ((error = ifioctl(socket_afnet, SIOCSIFMTU, &ifr, curlwp)) != 0) goto eexit; } /* 0 is a valid fd, so init to -1 */ iface->raw_fd = -1; iface->udp_fd = -1; iface->arp_fd = -1; eexit: if (error) { kmem_free(iface, sizeof(*iface)); iface = NULL; } *ifacep = iface; return error; }
int codel_pfattach(struct pf_altq *a) { struct ifnet *ifp; if ((ifp = ifunit(a->ifname)) == NULL || a->altq_disc == NULL) return (EINVAL); return (altq_attach(&ifp->if_snd, ALTQT_CODEL, a->altq_disc, codel_enqueue, codel_dequeue, codel_request, NULL, NULL)); }
/* look up the queue state by the interface name and the queueing type. */ void * altq_lookup(const char *name, int type) { struct ifnet *ifp; if ((ifp = ifunit(name)) != NULL) { if (type != ALTQT_NONE && ifp->if_snd.altq_type == type) return (ifp->if_snd.altq_disc); } return (NULL); }
STATUS ifUnnumberedSet ( char *pIfName, /* Name of interface to configure */ char *pDstIp, /* Destination address of the point to point link */ char *pBorrowedIp, /* The borrowed IP address/router ID */ char *pDstMac /* Destination MAC address */ ) { int s, ret; struct ifnet *ifp; struct sockaddr_in sock; if(!(ifp = ifunit (pIfName))) return (ERROR); /* * Make sure that the interface with the "real" * pBorrowedIp is already brought up. */ bzero ((char *)&sock, sizeof (struct sockaddr_in)); sock.sin_family = AF_INET; sock.sin_len = sizeof (struct sockaddr_in); sock.sin_addr.s_addr = inet_addr (pBorrowedIp); if (!ifa_ifwithaddr ((struct sockaddr *)&sock)) return (EINVAL); /* We manually configure the interface to be IFF_UNNUMBERED */ s = splnet (); ifp->if_flags &= ~IFF_BROADCAST; ifp->if_flags |= IFF_UNNUMBERED; /* It's defined as IFF_POINTOPOINT */ splx (s); ret = ifAddrAdd (pIfName, pBorrowedIp, pDstIp, 0); if (ret != OK) return (ret); /* * For ethernet devices, we need to complete the route entry * just created by the above operation. The ATF_INCOMPLETE flag * will change the routing entry to contain the MAC address * of the destination's ethernet device. */ if (pDstMac != (char *)NULL) ret = arpAdd (pDstIp, pDstMac, ATF_PERM | ATF_INCOMPLETE); return (ret); }
int compat_ifioctl(struct socket *so, u_long ocmd, u_long cmd, void *data, struct lwp *l) { struct ifreq *ifr = data; struct ifnet *ifp = ifunit(ifr->ifr_name); if (!ifp) return ENXIO; return (*so->so_proto->pr_usrreq)(so, PRU_CONTROL, (struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)ifp, l); }
//------------------------------------------------------------------------------ // FUNCTION // // // DESCRIPTION // // // PARAMETERS // // // RETURN // // //------------------------------------------------------------------------------ void RT_ifp_flush(char *ifname) { struct radix_node_head *rnh; int i; struct ifnet *ifp; ifp = ifunit(ifname); for (i = 1; i <= AF_MAX; i++) { if ((rnh = rt_tables[i]) != NULL) { rnh->rnh_walktree(rnh, ifprt_delete, ifp); } } }
int priq_pfattach(struct pf_altq *a) { struct ifnet *ifp; int s, error; if ((ifp = ifunit(a->ifname)) == NULL || a->altq_disc == NULL) return (EINVAL); s = splnet(); error = altq_attach(&ifp->if_snd, ALTQT_PRIQ, a->altq_disc, priq_enqueue, priq_dequeue, priq_request, NULL, NULL); splx(s); return (error); }
static struct ifnet * find_interface(void) { struct ifnet * ifp = NULL; if (rootdevice[0]) { ifp = ifunit((char *)rootdevice); } if (ifp == NULL) { ifnet_head_lock_shared(); TAILQ_FOREACH(ifp, &ifnet_head, if_link) if ((ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)) == 0) break; ifnet_head_done(); }
//------------------------------------------------------------------------------ // FUNCTION // // // DESCRIPTION // // // PARAMETERS // // // RETURN // // //------------------------------------------------------------------------------ int net_clone_mac_init(char *inf) { struct ifnet *ifp; ifp = ifunit(inf); diag_printf("CLN MAC init,if %s=%x\n", inf, ifp); net_clone_stat=1; net_clone_if=ifp; net_clone_mac_addr[5]=0xaa; clnmac_detect=&net_clone_mac_detect; return 0; }
/* * Create a clone network interface. */ int if_clone_create(char *name, int len, caddr_t params) { struct if_clone *ifc; char *dp; int wildcard, bytoff, bitoff; int unit; int err; ifc = if_clone_lookup(name, &unit); if (ifc == NULL) return (EINVAL); ifnet_lock(); if (ifunit(name) != NULL) { ifnet_unlock(); return (EEXIST); } ifnet_unlock(); bytoff = bitoff = 0; wildcard = (unit < 0); /* * Find a free unit if none was given. */ if (wildcard) { while (bytoff < ifc->ifc_bmlen && ifc->ifc_units[bytoff] == 0xff) bytoff++; if (bytoff >= ifc->ifc_bmlen) return (ENOSPC); while ((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0) bitoff++; unit = (bytoff << 3) + bitoff; } if (unit > ifc->ifc_maxunit) return (ENXIO); err = (*ifc->ifc_create)(ifc, unit, params); if (err != 0) return (err); if (!wildcard) { bytoff = unit >> 3; bitoff = unit - (bytoff << 3); }
int do_address(const char *ifname, struct in_addr *addr, struct in_addr *net, struct in_addr *dst, int act) { const struct sockaddr_in *a, *n, *d; struct ifnet *ifp = ifunit(ifname); struct ifaddr *ifa; int retval; if (ifp == NULL) return 0; retval = 0; IFADDR_FOREACH(ifa, ifp) { if (ifa->ifa_addr->sa_family != AF_INET) continue; a = (const struct sockaddr_in *)(void *)ifa->ifa_addr; n = (const struct sockaddr_in *)(void *)ifa->ifa_netmask; if (ifa->ifa_flags & IFF_POINTOPOINT) d = (const struct sockaddr_in *)(void *) ifa->ifa_dstaddr; else d = NULL; if (act == 1) { addr->s_addr = a->sin_addr.s_addr; net->s_addr = n->sin_addr.s_addr; if (dst) { if (ifa->ifa_flags & IFF_POINTOPOINT) dst->s_addr = d->sin_addr.s_addr; else dst->s_addr = INADDR_ANY; } retval = 1; break; } if (addr->s_addr == a->sin_addr.s_addr && (net == NULL || net->s_addr == n->sin_addr.s_addr)) { retval = 1; break; } } return retval; }
int altq_priq_pfattach(struct pf_altq *a) { struct ifnet *ifp; int error; lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED); if ((ifp = ifunit(a->ifname)) == NULL || a->altq_disc == NULL) return (EINVAL); IFCQ_LOCK(&ifp->if_snd); error = altq_attach(IFCQ_ALTQ(&ifp->if_snd), ALTQT_PRIQ, a->altq_disc, altq_priq_enqueue, altq_priq_dequeue, NULL, altq_priq_request); IFCQ_UNLOCK(&ifp->if_snd); return (error); }
int cbq_pfattach(struct pf_altq *a) { struct ifnet *ifp; int s, error; if ((ifp = ifunit(a->ifname)) == NULL || a->altq_disc == NULL) return (EINVAL); #ifdef __NetBSD__ s = splnet(); #else s = splimp(); #endif error = altq_attach(&ifp->if_snd, ALTQT_CBQ, a->altq_disc, cbq_enqueue, cbq_dequeue, cbq_request, NULL, NULL); splx(s); return (error); }
unsigned short ifNameToIfIndex ( char * ifName /* a string describing the full interface name. */ /* e.g., "fei0" */ ) { FAST struct ifnet * ifp; int s; int ifIndex; /* Call ifunit under splnet protection as it is not protected */ s = splnet (); ifp = ifunit (ifName); ifIndex = (ifp != NULL) ? ifp->if_index : 0; splx (s); return (ifIndex); }
__dead static void worker(void *arg) { ifnet_t *ifp = ifunit(IFNAME_INT); unsigned int i = (uintptr_t)arg; struct mbuf *m = fill_packet(i); uint64_t n = 0; while (!run) /* spin-wait */; while (!done) { int error; error = npf_packet_handler(NULL, &m, ifp, PFIL_OUT); KASSERT(error == 0); n++; } npackets[i] = n; kthread_exit(0); }
static int cbq_ifattach(struct cbq_interface *ifacep) { int error = 0; char *ifacename; cbq_state_t *new_cbqp; struct ifnet *ifp; ifacename = ifacep->cbq_ifacename; if ((ifp = ifunit(ifacename)) == NULL) return (ENXIO); if (!ALTQ_IS_READY(&ifp->if_snd)) return (ENXIO); /* allocate and initialize cbq_state_t */ new_cbqp = malloc(sizeof(cbq_state_t), M_DEVBUF, M_WAITOK|M_ZERO); if (new_cbqp == NULL) return (ENOMEM); CALLOUT_INIT(&new_cbqp->cbq_callout); new_cbqp->cbq_qlen = 0; new_cbqp->ifnp.ifq_ = &ifp->if_snd; /* keep the ifq */ /* * set CBQ to this ifnet structure. */ error = altq_attach(&ifp->if_snd, ALTQT_CBQ, new_cbqp, cbq_enqueue, cbq_dequeue, cbq_request, &new_cbqp->cbq_classifier, acc_classify); if (error) { free(new_cbqp, M_DEVBUF); return (error); } /* prepend to the list of cbq_state_t's. */ new_cbqp->cbq_next = cbq_list; cbq_list = new_cbqp; return (0); }
int altq_priq_add(struct pf_altq *a) { struct priq_if *pif; struct ifnet *ifp; lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED); if ((ifp = ifunit(a->ifname)) == NULL) return (EINVAL); if (!ALTQ_IS_READY(IFCQ_ALTQ(&ifp->if_snd))) return (ENODEV); pif = priq_alloc(ifp, M_WAITOK, TRUE); if (pif == NULL) return (ENOMEM); /* keep the state in pf_altq */ a->altq_disc = pif; return (0); }
int priq_add_altq(struct pf_altq *a) { struct priq_if *pif; struct ifnet *ifp; if ((ifp = ifunit(a->ifname)) == NULL) return (EINVAL); if (!ifq_is_ready(&ifp->if_snd)) return (ENODEV); pif = kmalloc(sizeof(*pif), M_ALTQ, M_WAITOK | M_ZERO); pif->pif_bandwidth = a->ifbandwidth; pif->pif_maxpri = -1; pif->pif_ifq = &ifp->if_snd; ifq_purge_all(&ifp->if_snd); /* keep the state in pf_altq */ a->altq_disc = pif; return (0); }