#ifdef LABEL u_long TC_AddLabel(int OIf, u_long rhandle, Session *dest, RSB *rp) { tc_t *tch = (tc_t*)rhandle; struct fltrinfo *fltrinfo; struct flow_filter filter; int error; /* CBQ does not create kernel state for incoming flows */ if(tch == NULL || IsNumAPI(tch->in_if) || !if_vec[tch->in_if].if_up) { return TC_OK; } rsvp_error = 0; if (rsvp2altq_label(rp , dest , &filter) != 0) return(TC_ERROR); /* if((fh = cbq_set_labelfilter(tch->cbq_handle, rp, dest)) == NULL) { if(!rsvp_errno) rsvp_errno = RSVP_Err_TC_SYS_ERROR; return TC_ERROR; } return (u_long)fh; */ if ((error = qop_add_label(&fltrinfo, tch->clinfo, NULL, &filter, NULL)) != 0) { rsvp_errno = Set_Errno(RSVP_Err_TC_SYS_ERROR, error); return (TC_ERROR); } return ((u_long)fltrinfo); } static int rsvp2altq_label(RSB *rp, Session *dest, struct flow_filter *flp) { memset(flp, 0, sizeof(struct flow_filter)); switch (Obj_CType(dest->d_session)) { case ctype_SESSION_ipv4: case ctype_SESSION_ipv4GPI: flp->ff_flow.fi_family = AF_INET; flp->ff_flow.fi_dst = dest->d_session->sess4_addr; flp->ff_mask.mask_dst.s_addr = 0xffffffff; flp->ff_flow.fi_dport = dest->d_session->sess4_port; flp->ff_flow.fi_proto = dest->d_session->sess4_prot; flp->ff_flow.fi_src = rp->rs_filtstar->fst_p->fst_filtp->filt4_srcaddr.saddr; flp->ff_mask.mask_src.s_addr = 0xffffffff; flp->ff_flow.fi_sport = rp->rs_filtstar->fst_p->fst_filtp->filt4_srcport; flp->ff_flow.fi_label = rp->rs_labelout; break; case ctype_SESSION_lsp_tunv4: flp->ff_flow.fi_family = AF_INET; flp->ff_flow.fi_dst = dest->d_session->sesslsp_addr; flp->ff_mask.mask_dst.s_addr = 0xffffffff; flp->ff_flow.fi_dport = 0; flp->ff_flow.fi_proto = 0; flp->ff_flow.fi_src = 0; flp->ff_mask.mask_src.s_addr = 0; flp->ff_flow.fi_sport = 0; flp->ff_flow.fi_label = rp->rs_labelout; break; default: rsvp_errno = Set_Errno(RSVP_Err_UNKNOWN_CTYPE, Obj_CType(dest->d_session)); return (-1); break; } return (0); } int qop_add_label(struct fltrinfo **rp, struct classinfo *clinfo, const char *flname, const struct flow_filter *fltr, struct fltrinfo **conflict) { struct ifinfo *ifinfo; struct fltrinfo *fltrinfo; int error; if ((fltrinfo = calloc(1, sizeof(*fltrinfo))) == NULL) return (QOPERR_NOMEM); fltrinfo->clinfo = clinfo; fltrinfo->fltr = *fltr; #if 1 /* fix this */ fltrinfo->line_no = line_no; /* XXX */ fltrinfo->dontwarn = filter_dontwarn; /* XXX */ #endif if (flname != NULL) fltrinfo->flname = strdup(flname); else fltrinfo->flname = strdup("(null)"); /* dummy name */ /* check and save the filter */ ifinfo = clinfo->ifinfo; if ((error = add_filter_rule(ifinfo, fltrinfo, conflict)) != 0) goto err_ret; /* install the filter to the kernel */ if ((error = (cbq_add_label)(fltrinfo)) != 0) { remove_filter_rule(ifinfo, fltrinfo); goto err_ret; } /* link fltrinfo onto fltrlist of the class */ LIST_INSERT_HEAD(&clinfo->fltrlist, fltrinfo, next); if (rp != NULL) *rp = fltrinfo; return (0); err_ret: if (fltrinfo != NULL) { if (fltrinfo->flname != NULL) free(fltrinfo->flname); free(fltrinfo); } return (error); } static int cbq_add_label(struct fltrinfo *fltrinfo) { struct cbq_add_filter fltr_add; memset(&fltr_add, 0, sizeof(fltr_add)); strncpy(fltr_add.cbq_iface.cbq_ifacename, fltrinfo->clinfo->ifinfo->ifname, IFNAMSIZ); fltr_add.cbq_iface.cbq_ifacelen = strlen(fltrinfo->clinfo->ifinfo->ifname); fltr_add.cbq_class_handle = fltrinfo->clinfo->handle; fltr_add.cbq_filter = fltrinfo->fltr; if (ioctl(cbq_fd, CBQ_ADD_LABEL, &fltr_add) < 0) return (QOPERR_SYSCALL); fltrinfo->handle = fltr_add.cbq_filter_handle; return (0); } #endif