/* ****************************************************************************** * INTERPEAK SOURCE FILE * * Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmpls_cmd_mplsctl.c,v $ $Revision: 1.19.10.2 $ * $Source: /home/interpeak/CVSRoot/ipmpls/src/ipmpls_cmd_mplsctl.c,v $ * $Author: hsun $ * $State: Exp $ $Locker: $ * * INTERPEAK_COPYRIGHT_STRING * * Design and implementation by Jonas Rendel ****************************************************************************** */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #include "ipmpls_config.h" /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #ifdef IPMPLS_INCLUDE_CMD #define IPCOM_USE_CLIB_PROTO #include #include #include #include #include #include #include #include #include #include #include #include #include "ipmpls.h" #include "ipmpls_h.h" struct Ipmpls_op_cmd { char *name; Ip_u16 code; }; IP_STATIC struct Ipmpls_op_cmd ipmpls_op[] = { { "pop", IPMPLS_OP_POP }, { "peek", IPMPLS_OP_PEEK }, { "push", IPMPLS_OP_PUSH }, { "dlv", IPMPLS_OP_DLV }, { "fwd", IPMPLS_OP_FWD }, { "set", IPMPLS_OP_SET }, { "setrx", IPMPLS_OP_SET_RX }, { "rtab", IPMPLS_OP_SET_VR }, { "vr", IPMPLS_OP_SET_VR }, { IP_NULL, IPMPLS_OP_NOP }, }; IP_STATIC int ipmpls_cmd_handle_op(unsigned long sioc, char *key, char *labelspace, char *op, Ip_bool silent); IP_STATIC Ip_fd mpls_fd = IP_INVALID_SOCKET; /* *=========================================================================== * impls_cmd_handle_labelspace *=========================================================================== * Description: Label Space command handler * * Parameters: cmd - command * if_name - interface name * labelspace - label space * silent - silent flag * * Returns: 0 = success, * */ IP_STATIC int impls_cmd_handle_labelspace(int cmd, char *if_name, char *labelspace, Ip_bool silent) { struct Ipmpls_labelspace_req lreq; unsigned long sioc; int ret = -1; lreq.mls_family = 0; lreq.mls_ifindex = ipcom_if_nametoindex(if_name); lreq.mls_labelspace = labelspace ? ipcom_atoi(labelspace) : 0; switch (cmd) { case 'd': lreq.mls_labelspace = 0; /* fall through */ case 'a': sioc = IPMPLS_SIOCSLABELSPACEMPLS; break; case 'g': sioc = IPMPLS_SIOCGLABELSPACEMPLS; break; default: return ret; } ret = ipcom_socketioctl(mpls_fd, sioc, &lreq); if(((ret == 0) && (cmd == 'g')) && !silent) ipcom_printf("Interface: %s ,Labelspace: %d",if_name, lreq.mls_labelspace); return ret; } /* *=========================================================================== * ipmpls_cmd_handle_tunnel *=========================================================================== * Description: MPLS tunnel command handler. * * Parameters: cmd - IOCTL command * if_name - interoace name. * nhlfe_key - NHLFE key * mtu - MTU * * Returns: 0 = success, * */ IP_STATIC int ipmpls_cmd_handle_tunnel(int cmd, char *if_name, char *nhlfe_key, char *mtu) { int ret = -1; unsigned long sioc; struct Ip_ifreq ifreq; struct Ipmpls_label label; Ipmpls_ifreq_data data; char *d; ipcom_memset(&data, 0, sizeof(data)); d = ipcom_strchr(if_name,'#'); if (d) { *d++ = 0; data.vr = (Ip_u16)ipcom_atoi(d); } if (ipcom_strlen(if_name) >= IP_IFNAMSIZ) { return ret; } ipcom_strcpy(ifreq.ifr_name, if_name); ifreq.ip_ifr_data = &data; switch (cmd) { case 'a': if (mtu) data.mtu = ipcom_atoi(mtu); sioc = IPMPLS_SIOCMPLSTUNNELADD; break; case 'd': sioc = IPMPLS_SIOCMPLSTUNNELDEL; break; case 'g': sioc = IPMPLS_SIOCMPLSTUNNELGETOUT; break; case 'b': sioc = IPMPLS_SIOCMPLSTUNNELADDOUT; goto do_key; case 'u': sioc = IPMPLS_SIOCMPLSTUNNELDELOUT ; do_key: if (nhlfe_key) { label.ml_type = IPMPLS_LABEL_TYPE_KEY; label.u.ml_key = ipcom_atoi(nhlfe_key); label.ml_index = 0; label.__refcnt = 0; ipcom_memcpy(&ifreq.ip_ifr_data, &label, sizeof(label)); } else goto out; break; default: goto out; } ret = ipcom_socketioctl(mpls_fd, sioc, &ifreq); if ((sioc == IPMPLS_SIOCMPLSTUNNELGETOUT) && (ret == 0)) { ipcom_memcpy(&label, &ifreq.ip_ifr_data, sizeof(label)); ipcom_printf("NHLFE Key: %d\n",label.u.ml_key); } out: return ret; } /* *=========================================================================== * ipmpls_cmd_handle_nhlfe *=========================================================================== * Description: NHLFE command handler * * Parameters: cmd - Command * nlhfe_key - Key * op - Operation Code String * mtu - MTU op string * silent - Silent flag * * Returns: 0 = success, * */ IP_STATIC int ipmpls_cmd_handle_nhlfe(int cmd, char *nhlfe_key, char *op, char *mtu, Ip_bool silent, Ip_u8 ttl) { int ret = -1; unsigned long sioc; struct Ipmpls_out_label_req olreq; ipcom_memset(&olreq, 0 , sizeof(olreq)); olreq.mol_mtu = mtu ? ipcom_atoi(mtu) : 0; olreq.mol_propagate_ttl = ttl; if (!nhlfe_key) goto out; switch (cmd) { case 'a': if (op) { ret = ipmpls_cmd_handle_op(IPMPLS_SIOCSMPLSOUTINSTR, nhlfe_key, IP_NULL, op, silent); goto out; } else sioc = IPMPLS_SIOCMPLSNHLFEADD; break; case 'd': sioc = IPMPLS_SIOCMPLSNHLFEDEL; break; case 'g': sioc = IPMPLS_SIOCMPLSNHLFEGET; break; default: goto out; } olreq.mol_label.ml_type = IPMPLS_LABEL_TYPE_KEY; olreq.mol_label.u.ml_key = ipcom_atoi(nhlfe_key); olreq.mol_label.ml_index = 0; if ((ret = ipcom_socketioctl(mpls_fd, sioc, &olreq)) == 0) { if (!silent && cmd == 'a') { ipcom_printf("NHLFE Key: %lu"IP_LF, olreq.mol_label.u.ml_key); } else if (cmd == 'g') { char buf[30]; (void)ipcom_strftime(buf, sizeof(buf), "%Y/%m/%d %H:%M:%S", ipcom_localtime((Ip_time_t*)&olreq.mol_age)); if (!silent) { ipcom_printf("NHLFE Key : %lu"IP_LF, olreq.mol_label.u.ml_key); ipcom_printf("Label Space: %u"IP_LF, olreq.mol_label.ml_index); ipcom_printf("Age : %s"IP_LF, buf); ipcom_printf("MTU : %lu"IP_LF, olreq.mol_mtu); ipcom_printf("TTL : %d"IP_LF, olreq.mol_propagate_ttl); } (void)ipcom_sprintf(buf, "%lu", olreq.mol_label.u.ml_key); if ((ret = ipmpls_cmd_handle_op(IPMPLS_SIOCGMPLSOUTINSTR, buf, IP_NULL, IP_NULL, silent)) < 0) { if (!silent) ipcom_printf("Operations: No label operations found"IP_LF); ret = 0; } } } out: return ret; } /* *=========================================================================== * ipmpls_cmd_handle_ilm *=========================================================================== * Description: ILM command handler * * Parameters: cmd - ILM command * ilm_key - ILM key * proto - Protocol string * op - Operation Code string * silent - Silent flag * * Returns: 0 = success, * */ IP_STATIC int ipmpls_cmd_handle_ilm(int cmd, char *ilm_key, char *proto, char *op, Ip_bool silent) { int ret = -1; unsigned long sioc; struct Ipmpls_in_label_req ilreq; char *labelspace; if (!ilm_key) goto out; labelspace = strchr(ilm_key, ':'); if(labelspace) *labelspace++ = 0; ipcom_memset(&ilreq, 0 , sizeof(ilreq)); switch (cmd) { case 'a': if (op) { ret = ipmpls_cmd_handle_op(IPMPLS_SIOCSMPLSININSTR, ilm_key, labelspace, op, silent); goto out; } else { sioc = IPMPLS_SIOCMPLSILMADD; if (proto && (ipcom_strcmp("ipv4",proto) == 0)) ilreq.mil_proto = IP_IPPROTO_IP; else if (proto && (ipcom_strcmp("ipv6",proto) == 0)) ilreq.mil_proto = IP_IPPROTO_IPV6; else goto out; } break; case 'd': sioc = IPMPLS_SIOCMPLSILMDEL; break; case 'g': sioc = IPMPLS_SIOCMPLSILMGET; break; default: goto out; } ilreq.mil_label.ml_type = IPMPLS_LABEL_TYPE_GEN; ilreq.mil_label.u.ml_gen = ipcom_atoi(ilm_key); ilreq.mil_label.ml_index = labelspace ? ipcom_atoi(labelspace) : 0; if ((ret = ipcom_socketioctl(mpls_fd, sioc, &ilreq)) == 0) { if (cmd == 'g') { char buf[30]; (void)ipcom_strftime(buf, sizeof(buf), "%Y/%m/%d %H:%M:%S", ipcom_localtime((Ip_time_t*)&ilreq.mil_age)); if (!silent) { ipcom_printf("Label : %lu"IP_LF, ilreq.mil_label.u.ml_gen); ipcom_printf("Label Space: %d"IP_LF, ilreq.mil_label.ml_index); ipcom_printf("Age : %s"IP_LF, buf); ipcom_printf("Protocol : %s"IP_LF, ilreq.mil_proto == IP_IPPROTO_IP ? "ipv4" : "ipv6"); } if ((ret = ipmpls_cmd_handle_op(IPMPLS_SIOCGMPLSININSTR, ilm_key, labelspace, IP_NULL, silent)) < 0) { if (!silent) ipcom_printf("Operations : No label operations found"IP_LF); ret = 0; } } } out: return ret; } /* *=========================================================================== * ipmpls_cmd_handle_xc *=========================================================================== * Description: Cross-Connect command handler * * Parameters: cmd - command * ilm_key - ILM key * nhlfe_key - NHLFE key * * Returns: 0 = success, * */ IP_STATIC int ipmpls_cmd_handle_xc(int cmd, char *ilm_key, char *nhlfe_key) { int ret = -1; struct Ipmpls_xconnect_req xcreq; unsigned long sioc; char *labelspace; if ((!ilm_key) || (!nhlfe_key)) goto out; switch (cmd) { case 'b': sioc = IPMPLS_SIOCMPLSXCADD; break; case 'u': sioc = IPMPLS_SIOCMPLSXCDEL; break; case 'g': sioc = IPMPLS_SIOCMPLSXCGET; break; default: goto out; } labelspace = ipcom_strchr(ilm_key, ':'); if (labelspace) *labelspace++ = 0; xcreq.mx_in.ml_type = IPMPLS_LABEL_TYPE_GEN; xcreq.mx_in.u.ml_gen = ipcom_atoi(ilm_key); xcreq.mx_in.ml_index = labelspace ? ipcom_atoi(labelspace) : 0; xcreq.mx_out.ml_type = IPMPLS_LABEL_TYPE_KEY; xcreq.mx_out.u.ml_key = ipcom_atoi(nhlfe_key); xcreq.mx_out.ml_index = 0; ret = ipcom_socketioctl(mpls_fd, sioc, &xcreq); out: return ret; } /* *=========================================================================== * impls_cmd_ll_ntop *=========================================================================== * Description: Creates a string representation of the hardware address. * Parameters: dl - The hardware address. * strptr - Will hold the sting representation of the address. * strlen - The length of the buffer pointer to by 'strptr' * Returns: The string represenstion. * */ #if 0 IP_STATIC IP_CONST char * ipmpls_cmd_ll_ntop(struct Ip_sockaddr_ll *ll, char *str, Ip_size_t len) { int alen; alen = ll->sll_halen; if (alen > 0) { int x; int slen; for (x = 0; x < alen; x++) { slen = len - x * 3; if (slen < 0) break; ipcom_snprintf(&str[x * 3], slen, "%02x%s", ll->sll_addr[x], x + 1 == alen ? "\0" : ":"); } } return str; } #endif /* *=========================================================================== * ipmpls_cmd_handle_op( *=========================================================================== * Description: Operation code command handler * * Parameters: sioc - IOCTL command * key - Key string * labelspace - Labe Space string * op - Operation Code String * silent - Silent flag * * Returns: 0 = success, * */ IP_STATIC int ipmpls_cmd_handle_op(unsigned long sioc, char *key, char* labelspace, char *op, Ip_bool silent) { struct Ipmpls_instr_req opreq; int ret = -1; int i = 0; ipcom_memset(&opreq, 0, sizeof(opreq)); if ((sioc == IPMPLS_SIOCSMPLSININSTR) || (sioc == IPMPLS_SIOCGMPLSININSTR)) opreq.mir_label.ml_type = IPMPLS_LABEL_TYPE_GEN; else opreq.mir_label.ml_type = IPMPLS_LABEL_TYPE_KEY; opreq.mir_label.u.ml_gen = ipcom_atoi(key); opreq.mir_label.ml_index = labelspace ? ipcom_atoi(labelspace) : 0; if ((sioc == IPMPLS_SIOCSMPLSININSTR) || (sioc == IPMPLS_SIOCSMPLSOUTINSTR)) { int j; char *d; struct Ip_sockaddr *sa; /* Set operation */ for(i = 0; i < IPMPLS_NUM_OPS && op && *op; i++) { if (sioc == IPMPLS_SIOCSMPLSININSTR) opreq.mir_instr[i].mir_direction = IPMPLS_IN; else opreq.mir_instr[i].mir_direction = IPMPLS_OUT; /* Operations are stored as op:data:data:data:op:data:op:op */ if ((d = ipcom_strchr(op, ',')) != IP_NULL) *d++ = 0; /* Get opcode */ for (j = 0; ipmpls_op[j].name; j++) if (ipcom_strcmp(op, ipmpls_op[j].name) == 0) break; opreq.mir_instr[i].mir_opcode = ipmpls_op[j].code; /* Handle opcode */ switch (ipmpls_op[j].code) { case IPMPLS_OP_POP: case IPMPLS_OP_PEEK: case IPMPLS_OP_DLV: /* These ops do not come with any data */ op = d && *d ? --d : IP_NULL; break; case IPMPLS_OP_PUSH: case IPMPLS_OP_FWD: { char *c; /* Format op,key or op,type:labelspace:label */ if (!d || !*d) goto bad_data_out; /* Setup null-terminated label string */ op = ipcom_strchr(d, ','); if (op) *op = 0; c = ipcom_strchr(d,':'); if (c) { /* type:labelspace:label syntax */ *c = 0; opreq.mir_instr[i].mir_data.push.ml_type = ipcom_atoi(d); d = c + 1; c = ipcom_strchr(d,':'); if (!c) goto bad_data_out; *c = 0; opreq.mir_instr[i].mir_data.push.ml_index = ipcom_atoi(d); d = c + 1; opreq.mir_instr[i].mir_data.push.u.ml_key = ipcom_atoi(d); } else { /* key syntax */ opreq.mir_instr[i].mir_data.push.ml_type = IPMPLS_LABEL_TYPE_KEY; opreq.mir_instr[i].mir_data.push.u.ml_key = ipcom_atoi(d); opreq.mir_instr[i].mir_data.push.ml_index = 0; } } break; case IPMPLS_OP_SET: /* * Format: * NHLFE: op,, * ILM : op, */ if (!d || !*d) goto bad_data_out; if (sioc == IPMPLS_SIOCSMPLSOUTINSTR) { /* NHLFE SET */ /* Setup null-terminated interface string */ op = ipcom_strchr(d, ','); if (!op || !*op) goto bad_data_out; *op++ = 0; opreq.mir_instr[i].mir_data.set.mni_if = ipcom_if_nametoindex(d); d = op; } sa = &opreq.mir_instr[i].mir_data.set.a.sa; op = ipcom_strchr(d, ','); /* Setup null-terminated address string */ if (op) *op = 0; /* Convert address string to sockaddr */ if (ipcom_getsockaddrbyaddr(IP_AF_INET, d, sa) < 0) if (ipcom_getsockaddrbyaddr(IP_AF_INET6, d, sa) < 0) { if (ipcom_getsockaddrbyaddr(IP_AF_LINK, d, sa) < 0) goto bad_data_out; } break; case IPMPLS_OP_SET_RX: /* Format op, */ if (!d || !*d) goto bad_data_out; /* Setup null-terminated interface name string */ op = ipcom_strchr(d, ','); if (op) *op = 0; opreq.mir_instr[i].mir_data.set_rx = ipcom_if_nametoindex(d); break; case IPMPLS_OP_SET_VR: /* Format op, */ if (!d || !*d) goto bad_data_out; /* Setup null-terminated interface name string */ op = ipcom_strchr(d, ','); if (op) *op = 0; opreq.mir_instr[i].mir_data.set_rtab = ipcom_atoi(d); break; case IPMPLS_OP_NOP: /* oops. Invalid opname */ goto bad_op_out; } if (op) op++; } opreq.mir_instr_length = (Ip_u8)i; } ret = ipcom_socketioctl(mpls_fd, sioc, &opreq); if ((ret == 0) && ((sioc == IPMPLS_SIOCGMPLSININSTR) || (sioc == IPMPLS_SIOCGMPLSOUTINSTR))) { char buf[50]; if (!silent) ipcom_printf("Operations : "); /* Get operation */ for (i=0; i < opreq.mir_instr_length; i++) { if (i > 0) { if (!silent) ipcom_printf(","); } /* Handle opcode */ switch (opreq.mir_instr[i].mir_opcode) { case IPMPLS_OP_POP: if (!silent) ipcom_printf("pop"); break; case IPMPLS_OP_PEEK: if (!silent) ipcom_printf("peek"); break; case IPMPLS_OP_DLV: if (!silent) ipcom_printf("dlv,%s",opreq.mir_family == IP_IPPROTO_IP ? "ipv4" : "ipv6"); break; case IPMPLS_OP_PUSH: if (!silent) ipcom_printf("push,%lu",opreq.mir_instr[i].mir_data.push.u.ml_gen); break; case IPMPLS_OP_FWD: if (!silent) ipcom_printf("fwd,%lu:%lu:%lu", opreq.mir_instr[i].mir_data.push.ml_type, opreq.mir_instr[i].mir_data.push.ml_index, opreq.mir_instr[i].mir_data.push.u.ml_key); break; case IPMPLS_OP_SET: if (sioc == IPMPLS_SIOCGMPLSOUTINSTR) { char addrstr[64]; char namebuf[64]; void* addr = IP_NULL; struct Ip_sockaddr *sa = &opreq.mir_instr[i].mir_data.set.a.sa; switch (sa->sa_family) { #ifdef IPCOM_USE_INET case IP_AF_INET: addr = &opreq.mir_instr[i].mir_data.set.a.sin.sin_addr; break; #endif #ifdef IPCOM_USE_INET6 case IP_AF_INET6: addr = &opreq.mir_instr[i].mir_data.set.a.sin6.sin6_addr; break; #endif default: goto bad_data_out; } ipcom_inet_ntop(sa->sa_family, addr, addrstr, sizeof(addrstr)); /* NHFLE */ if (!silent) ipcom_printf("set,%s,%s", ipcom_if_indextoname(opreq.mir_instr[i].mir_data.set.mni_if, namebuf), addrstr); } else { /* ILM */ if (!silent) ipcom_printf("set,%s", ipcom_cmd_sockaddr_to_str(&opreq.mir_instr[i].mir_data.set.a.sa, IP_FALSE, IP_TRUE, buf, sizeof(buf))); } break; case IPMPLS_OP_SET_RX: if (!silent) ipcom_printf("setrx,%s",ipcom_if_indextoname(opreq.mir_instr[i].mir_data.set_rx, buf)); break; case IPMPLS_OP_SET_VR: if (!silent) ipcom_printf("vr,%lu",opreq.mir_instr[i].mir_data.set_rtab); break; case IPMPLS_OP_NOP: goto out; } } out: if (!silent) ipcom_printf(IP_LF); } return ret; bad_data_out: if (!silent) ipcom_fprintf(ip_stderr,"Invalid data for operation code: %s"IP_LF,op); return ret; bad_op_out: if (!silent) ipcom_fprintf(ip_stderr,"Invalid operation code: %s"IP_LF,op); return ret; } /* *=========================================================================== * ipmpls_cmd_handle_table *=========================================================================== * Description: Table command handler * * Parameters: cmd - command * table - table string * * Returns: 0 = success, * */ IP_STATIC int ipmpls_cmd_handle_table(int cmd, char *table) { int ret = -1; unsigned long sioc; (void)cmd; if (table && (ipcom_strcmp(table,"nhlfe") == 0)) sioc = IPMPLS_SIOCMPLSNHLFEFLUSH; else if (table && (ipcom_strcmp(table,"ilm") == 0)) sioc = IPMPLS_SIOCMPLSILMFLUSH; else goto out; ret = ipcom_socketioctl(mpls_fd, sioc, IP_NULL); out: return ret; } /* **************************************************************************** * 10 GLOBAL FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipdhcps_cmd_dhcps *=========================================================================== * Description: Shell command used to start,stop and configure the DHCP * server. * Parameters: argc - The number of arguments passed to the command. * argv - The arguments passed to the command. * Returns: 0 = success, * */ IP_GLOBAL int ipmpls_cmd_mplsctl(int argc, char **argv) { char *op = IP_NULL; char *ilm_key = IP_NULL; char *nhlfe_key = IP_NULL; char *if_name = IP_NULL; char *proto = IP_NULL; char *mtu = IP_NULL; char *labelspace = IP_NULL; char *table = IP_NULL; char *vr = IP_NULL; int ret = -1; int cmd = 0; int opt; int cur_vr; int new_vr; Ip_bool silent = IP_FALSE; Ip_u8 ttl = 0; if (argc < 3) goto usage; #ifndef IP_PORT_LAS new_vr = cur_vr = ipcom_proc_vr_get(); #else (void)cur_vr; #endif ipcom_getopt_clear(); while ((opt = ipcom_getopt(argc, argv, "stadgbuf:i:n:l:I:o:m:p:V:")) != -1) { switch (opt) { case 'f': table = ip_optarg; /* fall through */ case 'a': case 'd': case 'g': case 'b': case 'u': cmd = opt; break; case 'i': ilm_key = ip_optarg; break; case 'n': nhlfe_key = ip_optarg; break; case 'l': labelspace = ip_optarg; break; case 'I': if_name = ip_optarg; break; case 'o': op = ip_optarg; break; case 'p': proto = ip_optarg; break; case 'm': mtu = ip_optarg; break; case 'V': vr = ip_optarg; break; case 's': silent = IP_TRUE; break; case 't': ttl = 1; break; default: goto usage; } } mpls_fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM,0); if (mpls_fd < 0) { ipcom_fprintf(ip_stderr, "Failed to open socket with error code %d (%s)"IP_LF, ipcom_errno, ipcom_strerror(ipcom_errno)); return -1; } if (vr != IP_NULL) { new_vr = ipcom_atoi(vr); #ifdef IP_PORT_LAS ret = ipcom_setsockopt(mpls_fd, IP_SOL_SOCKET, IP_SO_X_VR, &new_vr, sizeof(new_vr)); if (ret < 0) { ipcom_fprintf(ip_stderr, "Failed to set VR to %d"IP_LF, new_vr); return -1; } #else ipcom_proc_vr_set(new_vr); #endif } switch (cmd) { case 'a': case 'd': if (if_name && labelspace) ret = impls_cmd_handle_labelspace(cmd, if_name, labelspace, silent); else if (if_name) ret = ipmpls_cmd_handle_tunnel(cmd, if_name, nhlfe_key, mtu); else if (nhlfe_key) ret = ipmpls_cmd_handle_nhlfe(cmd, nhlfe_key, op, mtu, silent, ttl); else if (ilm_key) ret = ipmpls_cmd_handle_ilm(cmd, ilm_key, proto, op, silent); break; case 'g': if (if_name) { ret = impls_cmd_handle_labelspace(cmd, if_name, IP_NULL, silent); if (ret < 0) ret = ipmpls_cmd_handle_tunnel(cmd, if_name, nhlfe_key, mtu); } if (nhlfe_key) ret = ipmpls_cmd_handle_nhlfe(cmd, nhlfe_key, IP_NULL, IP_NULL, silent, ttl); if (ilm_key) ret = ipmpls_cmd_handle_ilm(cmd, ilm_key, IP_NULL, IP_NULL, silent); break; case 'b': case 'u': if (ilm_key && nhlfe_key) ret = ipmpls_cmd_handle_xc(cmd, ilm_key, nhlfe_key); else if (if_name && nhlfe_key) ret = ipmpls_cmd_handle_tunnel(cmd, if_name, nhlfe_key, mtu); break; case 'f': ret = ipmpls_cmd_handle_table (cmd, table); break; } ipcom_socketclose(mpls_fd); #ifndef IP_PORT_LAS if (cur_vr != new_vr) ipcom_proc_vr_set(cur_vr); #endif if (ret < 0) { ipcom_fprintf(ip_stderr, "Failed with error code %d (%s)"IP_LF, ipcom_errno, ipcom_strerror(ipcom_errno)); } return ret; usage: ipcom_fprintf(ip_stderr, "Usage: mplsctl [-s] [-a] [-d] [-b] [-u] [-f ilm | nhlfe]"IP_LF "[-I ] [-n ] [-i ]"IP_LF "[-l