static int pack_mac(struct m_pedit_sel *sel, struct m_pedit_key *tkey, __u8 *mac) { int ret = 0; if (!(tkey->off & 0x3)) { tkey->mask = 0; tkey->val = ntohl(*((__u32 *)mac)); ret |= pack_key32(~0, sel, tkey); tkey->off += 4; tkey->mask = 0; tkey->val = ntohs(*((__u16 *)&mac[4])); ret |= pack_key16(~0, sel, tkey); } else if (!(tkey->off & 0x1)) { tkey->mask = 0; tkey->val = ntohs(*((__u16 *)mac)); ret |= pack_key16(~0, sel, tkey); tkey->off += 4; tkey->mask = 0; tkey->val = ntohl(*((__u32 *)(mac + 2))); ret |= pack_key32(~0, sel, tkey); } else { fprintf(stderr, "pack_mac: mac offsets must begin in 32bit or 16bit boundaries\n"); return -1; } return ret; }
static int pack_ipv6(struct m_pedit_sel *sel, struct m_pedit_key *tkey, __u32 *ipv6) { int ret = 0; int i; if (tkey->off & 0x3) { fprintf(stderr, "pack_ipv6: IPv6 offsets must begin in 32bit boundaries\n"); return -1; } for (i = 0; i < 4; i++) { tkey->mask = 0; tkey->val = ntohl(ipv6[i]); ret = pack_key32(~0, sel, tkey); if (ret) return ret; tkey->off += 4; } return 0; }
static int parse_u32(int *argc_p, char ***argv_p, struct tc_u32_sel *sel, int off, int offmask) { int res = -1; int argc = *argc_p; char **argv = *argv_p; __u32 key; __u32 mask; if (argc < 2) return -1; if (get_u32(&key, *argv, 0)) return -1; argc--; argv++; if (get_u32(&mask, *argv, 16)) return -1; argc--; argv++; if (argc > 0 && strcmp(argv[0], "at") == 0) { NEXT_ARG(); if (parse_at(&argc, &argv, &off, &offmask)) return -1; } res = pack_key32(sel, key, mask, off, offmask); *argc_p = argc; *argv_p = argv; return res; }
int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type, __u32 retain, struct m_pedit_sel *sel, struct m_pedit_key *tkey) { __u32 mask[4] = { 0 }; __u32 val[4] = { 0 }; __u32 *m = &mask[0]; __u32 *v = &val[0]; __u32 o = 0xFF; int res = -1; int argc = *argc_p; char **argv = *argv_p; if (argc <= 0) return -1; if (pedit_debug) printf("parse_cmd argc %d %s offset %d length %d\n", argc, *argv, tkey->off, len); if (len == 2) o = 0xFFFF; if (len == 4) o = 0xFFFFFFFF; if (matches(*argv, "invert") == 0) { *v = *m = o; } else if (matches(*argv, "set") == 0 || matches(*argv, "add") == 0) { if (matches(*argv, "add") == 0) tkey->cmd = TCA_PEDIT_KEY_EX_CMD_ADD; if (!sel->extended && tkey->cmd) { fprintf(stderr, "Non extended mode. only 'set' command is supported\n"); return -1; } NEXT_ARG(); if (parse_val(&argc, &argv, val, type)) return -1; } else if (matches(*argv, "preserve") == 0) { retain = 0; } else { if (matches(*argv, "clear") != 0) return -1; } argc--; argv++; if (argc && matches(*argv, "retain") == 0) { NEXT_ARG(); if (parse_val(&argc, &argv, &retain, TU32)) return -1; argc--; argv++; } if (len > 4 && retain != ~0) { fprintf(stderr, "retain is not supported for fields longer the 32 bits\n"); return -1; } if (type == TMAC) { res = pack_mac(sel, tkey, (__u8 *)val); goto done; } if (type == TIPV6) { res = pack_ipv6(sel, tkey, val); goto done; } tkey->val = *v; tkey->mask = *m; if (type == TIPV4) tkey->val = ntohl(tkey->val); if (len == 1) { res = pack_key8(retain, sel, tkey); goto done; } if (len == 2) { res = pack_key16(retain, sel, tkey); goto done; } if (len == 4) { res = pack_key32(retain, sel, tkey); goto done; } return -1; done: if (pedit_debug) printf("parse_cmd done argc %d %s offset %d length %d\n", argc, *argv, tkey->off, len); *argc_p = argc; *argv_p = argv; return res; }
int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type,__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) { __u32 mask = 0, val = 0; __u32 o = 0xFF; int res = -1; int argc = *argc_p; char **argv = *argv_p; if (argc <= 0) return -1; if (pedit_debug) printf("parse_cmd argc %d %s offset %d length %d\n",argc,*argv,tkey->off,len); if (len == 2) o = 0xFFFF; if (len == 4) o = 0xFFFFFFFF; if (matches(*argv, "invert") == 0) { retain = val = mask = o; } else if (matches(*argv, "set") == 0) { NEXT_ARG(); if (parse_val(&argc, &argv, &val, type)) return -1; } else if (matches(*argv, "preserve") == 0) { retain = mask = o; } else { if (matches(*argv, "clear") != 0) return -1; } argc--; argv++; if (argc && matches(*argv, "retain") == 0) { NEXT_ARG(); if (parse_val(&argc, &argv, &retain, TU32)) return -1; argc--; argv++; } tkey->val = val; if (len == 1) { tkey->mask = 0xFF; res = pack_key8(retain,sel,tkey); goto done; } if (len == 2) { tkey->mask = mask; res = pack_key16(retain,sel,tkey); goto done; } if (len == 4) { tkey->mask = mask; res = pack_key32(retain,sel,tkey); goto done; } return -1; done: if (pedit_debug) printf("parse_cmd done argc %d %s offset %d length %d\n",argc,*argv,tkey->off,len); *argc_p = argc; *argv_p = argv; return res; }