* Only supports the simplest policy routing settings, like: * `ff_ipfw -P 0 add 100 setfib 0 ip from 125.94.59.0/24 to any out` * `from 125.94.59.0/24` need set addr is '125.94.59.0', netmask is '255.255.255.0' * * More policy routing settings should use tool `ff_ipfw`. */
| 558 | * More policy routing settings should use tool `ff_ipfw`. |
| 559 | */ |
| 560 | static int |
| 561 | ff_ipfw_add_simple_v4(struct ff_port_cfg *port_cfg, struct ff_vlan_cfg *vlan_cfg, uint32_t fib_num) |
| 562 | { |
| 563 | struct ff_ipfw_pr_cfg *pr_cfg; |
| 564 | uint32_t nb_pr; |
| 565 | int ret = -1, fd, i; |
| 566 | int level = IPPROTO_IP, optname; |
| 567 | uint32_t rulebuf[1024]; |
| 568 | socklen_t sz; |
| 569 | ip_fw3_opheader *op3; |
| 570 | ipfw_obj_ctlv *ctlv; |
| 571 | struct ip_fw_rule *rule; |
| 572 | ipfw_insn *cmd; |
| 573 | ipfw_insn *action; |
| 574 | ipfw_insn_ip *cmd_ip; |
| 575 | int rule_len, ctlv_count = 1, cmd_count = 5, act_ofs = 4, cmd_ip_count = 3, action_count = 1; |
| 576 | uint32_t rule_num; |
| 577 | |
| 578 | if (port_cfg) { |
| 579 | pr_cfg = port_cfg->pr_cfg; |
| 580 | nb_pr = port_cfg->nb_pr; |
| 581 | } else if (vlan_cfg) { |
| 582 | pr_cfg = vlan_cfg->pr_cfg; |
| 583 | nb_pr = vlan_cfg->nb_pr; |
| 584 | } else { |
| 585 | return -1; |
| 586 | } |
| 587 | |
| 588 | fd = ff_socket(AF_INET, SOCK_RAW, IPPROTO_RAW); |
| 589 | if (fd < 0) { |
| 590 | printf("ff_set_ipfw ff_socket error\n"); |
| 591 | goto done; |
| 592 | } |
| 593 | |
| 594 | memset(rulebuf, 0, sizeof(rulebuf)); |
| 595 | /* Because `struct ip_fw_rule` has 1 cmd(`ipfw_insn`), so should (cmd_count - 1), and then routeup2 8 bytes */ |
| 596 | rule_len = sizeof(struct ip_fw_rule) + (cmd_count - 1) * sizeof(ipfw_insn); |
| 597 | rule_len = roundup2(rule_len, sizeof(uint64_t)); |
| 598 | sz = sizeof(ip_fw3_opheader) + sizeof(ipfw_obj_ctlv) + rule_len; |
| 599 | |
| 600 | op3 = (ip_fw3_opheader *)rulebuf; |
| 601 | op3->opcode = IP_FW_XADD; |
| 602 | |
| 603 | /* |
| 604 | * {head = {type = 3, flags = 0, length = 56}, count = 1, objsize = 0, version = 0 '\000', flags = 0 '\000'} |
| 605 | * type:IPFW_TLV_RULE_LIST(3), length:ctlv header length + rule total length |
| 606 | */ |
| 607 | ctlv = (ipfw_obj_ctlv *)(op3 + 1); |
| 608 | ctlv->head.type = IPFW_TLV_RULE_LIST; |
| 609 | ctlv->head.length = sizeof(ipfw_obj_ctlv) + rule_len; |
| 610 | ctlv->count = ctlv_count; |
| 611 | //rule->rulenum = rule_num; |
| 612 | rule = (struct ip_fw_rule *)(ctlv + 1); |
| 613 | |
| 614 | |
| 615 | /* Need rule num(100/200/300/400), ip/mask,fib num(0/1/2/3/4) */ |
| 616 | /* $124 = {act_ofs = 4, cmd_len = 5, spare = 0, set = 0 '\000', flags = 0 '\000', rulenum = 200, id = 0, cmd = {{opcode = 2 '\002', len = 3 '\003', arg1 = 0}}} |
| 617 | * act_ofs is 4 means jump four cmd, it's point to the first action's index, |
no test coverage detected