struct ofpbuf * flow_mod_match_conj(enum ofputil_protocol proto) { struct ofputil_flow_mod fm; struct ofpbuf acts; struct ofpact_ipv4 *a_set_field; struct ofpact_goto_table *a_goto; memset(&fm, 0, sizeof(fm)); fm.command = OFPFC_ADD; fm.table_id = 3; fm.new_cookie = htonll(0x123456789abcdef0); fm.cookie_mask = OVS_BE64_MAX; fm.importance = 0x9878; match_init_catchall(&fm.match); match_set_conj_id(&fm.match, 0xabcdef); ofpbuf_init(&acts, 64); ofpact_put_STRIP_VLAN(&acts); a_set_field = ofpact_put_SET_IPV4_DST(&acts); a_set_field->ipv4 = inet_addr("192.168.2.9"); a_goto = ofpact_put_GOTO_TABLE(&acts); a_goto->table_id = 100; fm.ofpacts = acts.data; fm.ofpacts_len = acts.size; return ofputil_encode_flow_mod(&fm, proto); }
static void parse_named_instruction(enum ovs_instruction_type type, char *arg, struct ofpbuf *ofpacts) { enum ofperr error; switch (type) { case OVSINST_OFPIT11_APPLY_ACTIONS: NOT_REACHED(); /* This case is handled by str_to_inst_ofpacts() */ break; case OVSINST_OFPIT11_WRITE_ACTIONS: /* XXX */ ovs_fatal(0, "instruction write-actions is not supported yet"); break; case OVSINST_OFPIT11_CLEAR_ACTIONS: ofpact_put_CLEAR_ACTIONS(ofpacts); break; case OVSINST_OFPIT13_METER: ofpact_put_METER(ofpacts)->meter_id = str_to_u32(arg); break; case OVSINST_OFPIT11_WRITE_METADATA: parse_metadata(ofpacts, arg); break; case OVSINST_OFPIT11_GOTO_TABLE: { struct ofpact_goto_table *ogt = ofpact_put_GOTO_TABLE(ofpacts); char *table_s = strsep(&arg, ","); if (!table_s || !table_s[0]) { ovs_fatal(0, "instruction goto-table needs table id"); } ogt->table_id = str_to_u8(table_s, "table"); break; } } /* If write_metadata is specified as an action AND an instruction, ofpacts could be invalid. */ error = ofpacts_verify(ofpacts->data, ofpacts->size); if (error) { ovs_fatal(0, "Incorrect instruction ordering"); } }
struct ofpbuf * flow_mod(enum ofputil_protocol proto) { struct ofputil_flow_mod fm; struct ofpbuf acts; struct ofpact_ipv4 *a_set_field; struct ofpact_goto_table *a_goto; char *error; /* * Taken from neutron OVS-agent, * modified for OF>=1.3. (NXM -> OXM) * NOTE(yamamoto): This needs to be writable. learn_parse() modifies it. */ char learn_args[] = "table=99," "priority=1," "hard_timeout=300," "OXM_OF_VLAN_VID[0..11]," "OXM_OF_ETH_DST[]=OXM_OF_ETH_SRC[]," "load:0->OXM_OF_VLAN_VID[]," "load:OXM_OF_TUNNEL_ID[]->OXM_OF_TUNNEL_ID[]," "output:OXM_OF_IN_PORT[]"; memset(&fm, 0, sizeof(fm)); fm.command = OFPFC_ADD; fm.table_id = 2; fm.new_cookie = htonll(0x123456789abcdef0); fm.cookie_mask = OVS_BE64_MAX; fm.importance = 0x9878; fill_match(&fm.match); ofpbuf_init(&acts, 64); ofpact_put_STRIP_VLAN(&acts); a_set_field = ofpact_put_SET_IPV4_DST(&acts); a_set_field->ipv4 = inet_addr("192.168.2.9"); error = learn_parse(learn_args, &acts); assert(error == NULL); a_goto = ofpact_put_GOTO_TABLE(&acts); a_goto->table_id = 100; fm.ofpacts = acts.data; fm.ofpacts_len = acts.size; return ofputil_encode_flow_mod(&fm, proto); }
void act_go(struct ofpbuf* buf, uint8_t tableId) { struct ofpact_goto_table *goTab = ofpact_put_GOTO_TABLE(buf); goTab->table_id = tableId; }