static VALUE pack_send_out_port( VALUE self, VALUE actions, VALUE options ) { VALUE r_port_number = HASH_REF( options, port_number ); VALUE r_max_len = HASH_REF( options, max_len ); append_action_output( openflow_actions_ptr( actions ), ( const uint32_t ) NUM2UINT( r_port_number ), ( const uint16_t ) NUM2UINT( r_max_len ) ); return self; }
static void do_flooding( packet_in packet_in, uint32_t in_port ) { openflow_actions *actions = create_actions(); append_action_output( actions, OFPP_ALL, OFPCML_NO_BUFFER ); buffer *packet_out; if ( packet_in.buffer_id == OFP_NO_BUFFER ) { buffer *frame = duplicate_buffer( packet_in.data ); fill_ether_padding( frame ); packet_out = create_packet_out( get_transaction_id(), packet_in.buffer_id, in_port, actions, frame ); free_buffer( frame ); } else { packet_out = create_packet_out( get_transaction_id(), packet_in.buffer_id, in_port, actions, NULL ); } send_openflow_message( packet_in.datapath_id, packet_out ); free_buffer( packet_out ); delete_actions( actions ); }
bool send_lldp( probe_timer_entry *port ) { buffer *lldp; lldp = create_lldp_frame( port->mac, port->datapath_id, port->port_no ); openflow_actions *actions = create_actions(); if ( !append_action_output( actions, port->port_no, UINT16_MAX ) ) { free_buffer( lldp ); error( "Failed to sent LLDP frame(%#" PRIx64 ", %u)", port->datapath_id, port->port_no ); return false; } uint32_t transaction_id = get_transaction_id(); buffer *packetout = create_packet_out( transaction_id, UINT32_MAX, OFPP_NONE, actions, lldp ); if ( !send_openflow_message( port->datapath_id, packetout ) ) { free_buffer( lldp ); free_buffer( packetout ); delete_actions( actions ); die( "send_openflow_message" ); } free_buffer( lldp ); free_buffer( packetout ); delete_actions( actions ); debug( "Sent LLDP frame(%#" PRIx64 ", %u)", port->datapath_id, port->port_no ); return true; }
static void send_flow_mod_receiving_lldp( sw_entry *sw, uint16_t hard_timeout, uint16_t priority ) { struct ofp_match match; memset( &match, 0, sizeof( struct ofp_match ) ); if ( !options.lldp_over_ip ) { match.wildcards = OFPFW_ALL & ~OFPFW_DL_TYPE; match.dl_type = ETH_ETHTYPE_LLDP; } else { match.wildcards = OFPFW_ALL & ~( OFPFW_DL_TYPE | OFPFW_NW_PROTO | OFPFW_NW_SRC_MASK | OFPFW_NW_DST_MASK ); match.dl_type = ETH_ETHTYPE_IPV4; match.nw_proto = IPPROTO_ETHERIP; match.nw_src = options.lldp_ip_src; match.nw_dst = options.lldp_ip_dst; } openflow_actions *actions = create_actions(); const uint16_t max_len = UINT16_MAX; append_action_output( actions, OFPP_CONTROLLER, max_len ); const uint16_t idle_timeout = 0; const uint32_t buffer_id = UINT32_MAX; const uint16_t flags = 0; buffer *flow_mod = create_flow_mod( get_transaction_id(), match, get_cookie(), OFPFC_ADD, idle_timeout, hard_timeout, priority, buffer_id, OFPP_NONE, flags, actions ); send_openflow_message( sw->datapath_id, flow_mod ); delete_actions( actions ); free_buffer( flow_mod ); debug( "Sent a flow_mod for receiving LLDP frames from %#" PRIx64 ".", sw->datapath_id ); }
static void handle_switch_ready( uint64_t datapath_id, void *user_data ) { UNUSED( user_data ); openflow_actions *actions = create_actions(); append_action_output( actions, OFPP_CONTROLLER, OFPCML_NO_BUFFER ); openflow_instructions *insts = create_instructions(); append_instructions_apply_actions( insts, actions ); buffer *flow_mod = create_flow_mod( get_transaction_id(), get_cookie(), 0, 0, OFPFC_ADD, 0, 0, OFP_LOW_PRIORITY, OFP_NO_BUFFER, 0, 0, OFPFF_SEND_FLOW_REM, NULL, insts ); send_openflow_message( datapath_id, flow_mod ); free_buffer( flow_mod ); delete_instructions( insts ); delete_actions( actions ); }
static void handle_packet_in( uint64_t datapath_id, packet_in message ) { openflow_actions *actions = create_actions(); append_action_output( actions, ( uint16_t ) ( message.in_port + 1 ), OFPCML_NO_BUFFER ); struct ofp_match match; set_match_from_packet( &match, message.in_port, 0, message.data ); buffer *flow_mod = create_flow_mod( get_transaction_id(), match, get_cookie(), OFPFC_ADD, 0, 0, OFP_HIGH_PRIORITY, message.buffer_id, OFPP_NONE, 0, actions ); send_openflow_message( datapath_id, flow_mod ); free_buffer( flow_mod ); delete_actions( actions ); }
static void do_flooding( packet_in packet_in ) { openflow_actions *actions = create_actions(); append_action_output( actions, OFPP_FLOOD, UINT16_MAX ); buffer *packet_out; if ( packet_in.buffer_id == UINT32_MAX ) { buffer *frame = duplicate_buffer( packet_in.data ); fill_ether_padding( frame ); packet_out = create_packet_out( get_transaction_id(), packet_in.buffer_id, packet_in.in_port, actions, frame ); free_buffer( frame ); } else { packet_out = create_packet_out( get_transaction_id(), packet_in.buffer_id, packet_in.in_port, actions, NULL ); } send_openflow_message( packet_in.datapath_id, packet_out ); free_buffer( packet_out ); delete_actions( actions ); }
static void send_packet( uint16_t destination_port, packet_in packet_in ) { openflow_actions *actions = create_actions(); append_action_output( actions, destination_port, UINT16_MAX ); struct ofp_match match; set_match_from_packet( &match, packet_in.in_port, 0, packet_in.data ); buffer *flow_mod = create_flow_mod( get_transaction_id(), match, get_cookie(), OFPFC_ADD, 60, 0, UINT16_MAX, UINT32_MAX, OFPP_NONE, OFPFF_SEND_FLOW_REM, actions ); send_openflow_message( packet_in.datapath_id, flow_mod ); free_buffer( flow_mod ); send_packet_out( packet_in, actions ); delete_actions( actions ); }
static void output_packet( const buffer *packet, uint64_t dpid, uint16_t port_no ) { openflow_actions *actions = create_actions(); append_action_output( actions, port_no, UINT16_MAX ); send_packet_out( dpid, actions, packet ); delete_actions( actions ); }
static void handle_packet_in( uint64_t datapath_id, packet_in message ) { if ( message.data == NULL ) { error( "data must not be NULL" ); return; } uint32_t in_port = get_in_port_from_oxm_matches( message.match ); if ( in_port == 0 ) { return; } openflow_actions *actions = create_actions(); append_action_output( actions, OFPP_ALL, OFPCML_NO_BUFFER ); openflow_instructions *insts = create_instructions(); append_instructions_apply_actions( insts, actions ); oxm_matches *match = create_oxm_matches(); set_match_from_packet( match, in_port, 0, message.data ); buffer *flow_mod = create_flow_mod( get_transaction_id(), get_cookie(), 0, 0, OFPFC_ADD, 60, 0, OFP_HIGH_PRIORITY, message.buffer_id, 0, 0, OFPFF_SEND_FLOW_REM, match, insts ); send_openflow_message( datapath_id, flow_mod ); free_buffer( flow_mod ); delete_oxm_matches( match ); delete_instructions( insts ); if ( message.buffer_id == OFP_NO_BUFFER ) { buffer *frame = duplicate_buffer( message.data ); fill_ether_padding( frame ); buffer *packet_out = create_packet_out( get_transaction_id(), message.buffer_id, in_port, actions, frame ); send_openflow_message( datapath_id, packet_out ); free_buffer( packet_out ); free_buffer( frame ); } delete_actions( actions ); }
static void do_flooding( packet_in packet_in ) { openflow_actions *actions = create_actions(); append_action_output( actions, OFPP_FLOOD, UINT16_MAX ); send_packet_out( packet_in, actions ); delete_actions( actions ); }
static int build_packet_out_actions( port_info *port, openflow_actions *actions, uint64_t dpid, uint16_t in_port ) { const uint16_t max_len = UINT16_MAX; if ( port->dpid == dpid && port->port_no == in_port ) { // don't send to input port return 0; } else { append_action_output( actions, port->port_no, max_len ); return 1; } }
static int build_packet_out_actions( port_info *port, openflow_actions *actions, uint64_t dpid, uint16_t in_port ) { if ( !port->external_link || port->switch_to_switch_reverse_link ) { // don't send to non-external port return 0; } if ( port->dpid == dpid && port->port_no == in_port ) { // don't send to input port return 0; } append_action_output( actions, port->port_no, UINT16_MAX ); return 1; }
static void send_packet( uint32_t destination_port, packet_in packet_in, uint32_t in_port ) { openflow_actions *actions = create_actions(); append_action_output( actions, destination_port, OFPCML_NO_BUFFER ); openflow_instructions *insts = create_instructions(); append_instructions_apply_actions( insts, actions ); oxm_matches *match = create_oxm_matches(); set_match_from_packet( match, in_port, NULL, packet_in.data ); buffer *flow_mod = create_flow_mod( get_transaction_id(), get_cookie(), 0, 0, OFPFC_ADD, 60, 0, OFP_HIGH_PRIORITY, packet_in.buffer_id, 0, 0, OFPFF_SEND_FLOW_REM, match, insts ); send_openflow_message( packet_in.datapath_id, flow_mod ); free_buffer( flow_mod ); delete_oxm_matches( match ); delete_instructions( insts ); if ( packet_in.buffer_id == OFP_NO_BUFFER ) { buffer *frame = duplicate_buffer( packet_in.data ); fill_ether_padding( frame ); buffer *packet_out = create_packet_out( get_transaction_id(), packet_in.buffer_id, in_port, actions, frame ); send_openflow_message( packet_in.datapath_id, packet_out ); free_buffer( packet_out ); free_buffer( frame ); } delete_actions( actions ); }
static void output_packet( buffer *packet, uint64_t dpid, uint16_t port_no ) { openflow_actions *actions = create_actions(); const uint16_t max_len = UINT16_MAX; append_action_output( actions, port_no, max_len ); const uint32_t transaction_id = get_transaction_id(); const uint32_t buffer_id = UINT32_MAX; const uint16_t in_port = OFPP_NONE; fill_ether_padding( packet ); buffer *packet_out = create_packet_out( transaction_id, buffer_id, in_port, actions, packet ); send_openflow_message( dpid, packet_out ); free_buffer( packet_out ); delete_actions( actions ); }
static void send_packet_out( uint64_t datapath_id, packet_in *message, uint16_t out_port ) { uint32_t buffer_id = message->buffer_id; uint16_t in_port = message->in_port; if ( datapath_id != message->datapath_id ) { buffer_id = UINT32_MAX; in_port = OFPP_NONE; } openflow_actions *actions = create_actions(); append_action_output( actions, out_port, UINT16_MAX ); const buffer *data = NULL; if ( buffer_id == UINT32_MAX ) { data = message->data; } buffer *packet_out = create_packet_out( get_transaction_id(), buffer_id, in_port, actions, data ); delete_actions( actions ); send_openflow_message( datapath_id, packet_out ); free_buffer( packet_out ); }
static int build_packet_out_actions( port_info *port, void *user_data ) { if ( !port->external_link || port->switch_to_switch_reverse_link ) { // don't send to non-external port return 0; } port_params *params = user_data; if ( port->dpid == params->switch_params->in_datapath_id && port->port_no == params->switch_params->in_port ) { // don't send to input port return 0; } int n_actions_original = params->actions->n_actions; uint16_t slice = params->switch_params->slice; uint16_t out_vid = params->switch_params->in_vid; bool found = get_port_vid( slice, port->dpid, port->port_no, &out_vid ); if ( found ) { if ( out_vid == VLAN_NONE ) { append_action_strip_vlan( params->actions ); } else { append_action_set_vlan_vid( params->actions, out_vid ); } } else { if ( !loose_mac_based_slicing_enabled() ) { return 0; } if ( !mac_slice_maps_exist( slice ) ) { return 0; } } const uint16_t max_len = UINT16_MAX; append_action_output( params->actions, port->port_no, max_len ); return params->actions->n_actions - n_actions_original; }
static void send_packet( uint16_t destination_port, packet_in packet_in ) { openflow_actions *actions = create_actions(); append_action_output( actions, destination_port, UINT16_MAX ); struct ofp_match match; set_match_from_packet( &match, packet_in.in_port, 0, packet_in.data ); buffer *flow_mod = create_flow_mod( get_transaction_id(), match, get_cookie(), OFPFC_ADD, 60, 0, UINT16_MAX, packet_in.buffer_id, OFPP_NONE, OFPFF_SEND_FLOW_REM, actions ); send_openflow_message( packet_in.datapath_id, flow_mod ); free_buffer( flow_mod ); if ( packet_in.buffer_id == UINT32_MAX ) { buffer *frame = duplicate_buffer( packet_in.data ); fill_ether_padding( frame ); buffer *packet_out = create_packet_out( get_transaction_id(), packet_in.buffer_id, packet_in.in_port, actions, frame ); send_openflow_message( packet_in.datapath_id, packet_out ); free_buffer( packet_out ); free_buffer( frame ); } delete_actions( actions ); }
static void output_packet( const buffer *packet, uint64_t dpid, uint16_t port_no, uint16_t out_vid ) { openflow_actions *actions = create_actions(); uint16_t in_vid = VLAN_NONE; if ( packet_type_eth_vtag( packet ) ) { packet_info packet_info = get_packet_info( packet ); in_vid = packet_info.vlan_vid; } if ( out_vid != in_vid ) { if ( in_vid != VLAN_NONE && out_vid == VLAN_NONE ) { append_action_strip_vlan( actions ); } else { append_action_set_vlan_vid( actions, out_vid ); } } const uint16_t max_len = UINT16_MAX; append_action_output( actions, port_no, max_len ); send_packet_out( dpid, actions, packet ); delete_actions( actions ); }
static void send_flow_mod( uint64_t datapath_id, uint8_t *macsa, uint8_t *macda, uint16_t out_port ) { struct ofp_match match; memset( &match, 0, sizeof( match ) ); match.wildcards = ( OFPFW_ALL & ~( OFPFW_DL_SRC | OFPFW_DL_DST ) ); memcpy( match.dl_src, macsa, OFP_ETH_ALEN ); memcpy( match.dl_dst, macda, OFP_ETH_ALEN ); uint16_t idle_timeout = 0; uint16_t hard_timeout = 10; uint16_t priority = UINT16_MAX; uint32_t buffer_id = UINT32_MAX; uint16_t out_port_for_delete_command = OFPP_NONE; uint16_t flags = OFPFF_SEND_FLOW_REM; openflow_actions *actions = create_actions(); append_action_output( actions, out_port, UINT16_MAX ); buffer *flow_mod = create_flow_mod( get_transaction_id(), match, get_cookie(), OFPFC_ADD, idle_timeout, hard_timeout, priority, buffer_id, out_port_for_delete_command, flags, actions ); delete_actions( actions ); send_openflow_message( datapath_id, flow_mod ); free_buffer( flow_mod ); }
static void modify_flow_entry( const pathresolver_hop *h, const buffer *original_packet, uint16_t idle_timeout ) { const uint32_t wildcards = 0; struct ofp_match match; set_match_from_packet( &match, h->in_port_no, wildcards, original_packet ); uint32_t transaction_id = get_transaction_id(); openflow_actions *actions = create_actions(); const uint16_t max_len = UINT16_MAX; append_action_output( actions, h->out_port_no, max_len ); const uint16_t hard_timeout = 0; const uint16_t priority = UINT16_MAX; const uint32_t buffer_id = UINT32_MAX; const uint16_t flags = 0; buffer *flow_mod = create_flow_mod( transaction_id, match, get_cookie(), OFPFC_ADD, idle_timeout, hard_timeout, priority, buffer_id, h->out_port_no, flags, actions ); send_openflow_message( h->dpid, flow_mod ); delete_actions( actions ); free_buffer( flow_mod ); }
static void recv_packet_from_tun() { char data[ PKT_BUF_SIZE ]; ssize_t ret; ret = read( fd, data, PKT_BUF_SIZE ); if ( ret <= 0 ) { return; } debug( "%zd bytes packet received from tun interface (fd = %d).", ret, fd ); // FIXME: we need to parse the ipv4 packet. ipv4_header_t *ip_header = ( ipv4_header_t * ) data; host_entry *entry = lookup_host( ntohl( ip_header->daddr ) ); struct in_addr addr; addr.s_addr = ip_header->daddr; if ( entry == NULL ) { error( "Failed to resolve host location (ip = %s).", inet_ntoa( addr ) ); return; } // create an Ethernet frame and send a packet-out void *p; uint16_t *type; buffer *frame; buffer *pout; openflow_actions *actions; size_t frame_length = ETH_ADDRLEN * 2 + 2 + ( size_t ) ret; frame = alloc_buffer_with_length( frame_length ); p = append_back_buffer( frame, ETH_ADDRLEN ); memcpy( p, entry->mac, ETH_ADDRLEN ); p = append_back_buffer( frame, ETH_ADDRLEN ); memcpy( p, redirector_mac, ETH_ADDRLEN ); type = append_back_buffer( frame, 2 ); *type = htons( ETH_ETHTYPE_IPV4 ); p = append_back_buffer( frame, ( size_t ) ret ); memcpy( p, data, ( size_t ) ret ); debug( "Sending a packet-out to a switch (ip = %s, dpid = %#" PRIx64 ", port = %u).", inet_ntoa( addr ), entry->dpid, entry->port ); actions = create_actions(); append_action_output( actions, entry->port, UINT16_MAX ); pout = create_packet_out( get_transaction_id(), UINT32_MAX, OFPP_NONE, actions, frame ); send_openflow_message( entry->dpid, pout ); free_buffer( frame ); free_buffer( pout ); delete_actions( actions ); }
static void handle_switch_ready( uint64_t datapath_id, void *user_data ) { UNUSED( user_data ); openflow_actions *actions = create_actions(); append_action_output( actions, OFPP_CONTROLLER, OFPCML_NO_BUFFER ); openflow_instructions *insts = create_instructions(); append_instructions_apply_actions( insts, actions ); buffer *flow_mod = create_flow_mod( get_transaction_id(), get_cookie(), 0, 0, OFPFC_ADD, 0, 0, OFP_LOW_PRIORITY, OFP_NO_BUFFER, 0, 0, OFPFF_SEND_FLOW_REM, NULL, insts ); send_openflow_message( datapath_id, flow_mod ); free_buffer( flow_mod ); delete_instructions( insts ); // sleep(2000); info("sending ARP config: flood - %d",datapath_id); uint32_t dest = OFPP_ALL; oxm_matches *match2 = create_oxm_matches(); append_oxm_match_eth_type( match2, 0x0806); openflow_actions *actions2 = create_actions(); append_action_output( actions2, dest, OFPCML_NO_BUFFER ); openflow_instructions *insts2 = create_instructions(); append_instructions_apply_actions( insts2, actions2 ); buffer *flow_mod2 = create_flow_mod( get_transaction_id(), get_cookie(), 0, 0, OFPFC_ADD, 0, 0, OFP_HIGH_PRIORITY, OFP_NO_BUFFER, 0, 0, OFPFF_SEND_FLOW_REM, match2, insts2 ); send_openflow_message( datapath_id, flow_mod2 ); free_buffer( flow_mod2 ); delete_oxm_matches( match2 ); delete_instructions( insts2 ); // sleep(2000); info("sending second config: match on eth src"); uint8_t eth_src[ OFP_ETH_ALEN ] = {0x0,0x24,0xe8,0x77,0xa5,0x32}; uint8_t set_src[ OFP_ETH_ALEN ] = {0x0,0x10,0x18,0x56,0xab,0xc2}; uint8_t eth_mask[ OFP_ETH_ALEN ] = {0xff,0xff,0xff,0xff,0xff,0xff}; oxm_matches *match3 = create_oxm_matches(); append_oxm_match_eth_type( match3, 0x0800); append_oxm_match_eth_src( match3,eth_src,eth_mask); // append_oxm_match_in_port( match2, 2); // dest = 1; openflow_actions *actions3 = create_actions(); append_action_set_field_eth_src( actions3, set_src ); append_action_push_mpls(actions3,0x8847); append_action_set_field_mpls_label(actions3,412095); append_action_output( actions3, 3, OFPCML_NO_BUFFER ); openflow_instructions *insts3 = create_instructions(); append_instructions_apply_actions( insts3, actions3 ); buffer *flow_mod3 = create_flow_mod( get_transaction_id(), get_cookie(), 0, 0, OFPFC_ADD, 0, 0, OFP_HIGH_PRIORITY, OFP_NO_BUFFER, 0, 0, OFPFF_SEND_FLOW_REM, match3, insts3 ); send_openflow_message( datapath_id, flow_mod3 ); free_buffer( flow_mod3 ); delete_oxm_matches( match3 ); delete_instructions( insts3 ); info("done sending"); // sleep(2000); info("sending config:match mpls label -> pop mpls, set dest eth"); oxm_matches *match4 = create_oxm_matches(); append_oxm_match_eth_type( match4, 0x8847); append_oxm_match_mpls_label(match4, 412095); uint8_t set_src2[ OFP_ETH_ALEN ] = {0x0,0x24,0xe8,0x77,0xa5,0x32}; openflow_actions *actions4 = create_actions(); append_action_pop_mpls(actions4, 0x0800); append_action_output( actions4, 1, OFPCML_NO_BUFFER ); append_action_set_field_eth_src( actions4, set_src2 ); openflow_instructions *insts4 = create_instructions(); append_instructions_apply_actions( insts4, actions4 ); buffer *flow_mod4 = create_flow_mod( get_transaction_id(), get_cookie(), 0, 0, OFPFC_ADD, 0, 0, OFP_HIGH_PRIORITY, OFP_NO_BUFFER, 0, 0, OFPFF_SEND_FLOW_REM, match4, insts4 ); send_openflow_message( 0x00101856ab98 , flow_mod4); free_buffer( flow_mod4 ); delete_oxm_matches( match4 ); delete_instructions( insts4 ); info("sending second config: match on eth src"); uint8_t set_src3[ OFP_ETH_ALEN ] = {0x0,0x10,0x18,0x56,0xab,0xc2}; oxm_matches *match5 = create_oxm_matches(); append_oxm_match_eth_type( match5, 0x0800); // append_oxm_match_eth_src( match3,eth_src,eth_mask); // append_oxm_match_in_port( match2, 2); // dest = 1; openflow_actions *actions5 = create_actions(); append_action_set_field_eth_src( actions5, set_src3 ); append_action_push_mpls(actions5,0x8847); append_action_set_field_mpls_label(actions5,442095); append_action_output( actions5, 3, OFPCML_NO_BUFFER ); openflow_instructions *insts5 = create_instructions(); append_instructions_apply_actions( insts5, actions5 ); buffer *flow_mod5 = create_flow_mod( get_transaction_id(), get_cookie(), 0, 0, OFPFC_ADD, 0, 0, OFP_HIGH_PRIORITY, OFP_NO_BUFFER, 0, 0, OFPFF_SEND_FLOW_REM, match5, insts5 ); send_openflow_message( datapath_id, flow_mod5 ); free_buffer( flow_mod5 ); delete_oxm_matches( match5 ); delete_instructions( insts5 ); info("done sending"); }
static void handle_switch_ready( uint64_t datapath_id, void *user_data ) { UNUSED( user_data ); openflow_actions *actions = create_actions(); append_action_output( actions, OFPP_CONTROLLER, OFPCML_NO_BUFFER ); openflow_instructions *insts = create_instructions(); append_instructions_apply_actions( insts, actions ); buffer *flow_mod = create_flow_mod( get_transaction_id(), get_cookie(), 0, 0, OFPFC_ADD, 0, 0, OFP_LOW_PRIORITY, OFP_NO_BUFFER, 0, 0, OFPFF_SEND_FLOW_REM, NULL, insts ); send_openflow_message( datapath_id, flow_mod ); free_buffer( flow_mod ); delete_instructions( insts ); // sleep(2000); info("sending ARP config to %d",datapath_id); uint32_t dest = OFPP_ALL; oxm_matches *match2 = create_oxm_matches(); append_oxm_match_eth_type( match2, 0x0806); openflow_actions *actions2 = create_actions(); append_action_output( actions2, dest, OFPCML_NO_BUFFER ); openflow_instructions *insts2 = create_instructions(); append_instructions_apply_actions( insts2, actions2 ); buffer *flow_mod2 = create_flow_mod( get_transaction_id(), get_cookie(), 0, 0, OFPFC_ADD, 0, 0, OFP_HIGH_PRIORITY, OFP_NO_BUFFER, 0, 0, OFPFF_SEND_FLOW_REM, match2, insts2 ); send_openflow_message( datapath_id, flow_mod2 ); free_buffer( flow_mod2 ); delete_oxm_matches( match2 ); delete_instructions( insts2 ); // sleep(2000); info("sending second config: ipv4"); oxm_matches *match3 = create_oxm_matches(); append_oxm_match_eth_type( match3, 0x0800); // append_oxm_match_in_port( match2, 2); // dest = 1; openflow_actions *actions3 = create_actions(); append_action_push_mpls(actions3,0x8847); append_action_set_field_mpls_label(actions3,4120955); append_action_output( actions3, dest, OFPCML_NO_BUFFER ); openflow_instructions *insts3 = create_instructions(); append_instructions_apply_actions( insts3, actions3 ); buffer *flow_mod3 = create_flow_mod( get_transaction_id(), get_cookie(), 0, 0, OFPFC_ADD, 0, 0, OFP_HIGH_PRIORITY, OFP_NO_BUFFER, 0, 0, OFPFF_SEND_FLOW_REM, match3, insts3 ); send_openflow_message( datapath_id, flow_mod3 ); free_buffer( flow_mod3 ); delete_oxm_matches( match3 ); delete_instructions( insts3 ); info("done sending"); // sleep(2000); info("sending third config"); oxm_matches *match4 = create_oxm_matches(); append_oxm_match_eth_type( match4, 0x8847); append_oxm_match_mpls_label(match4, 4120955); openflow_actions *actions4 = create_actions(); append_action_pop_mpls(actions4, 0x0800); append_action_output( actions4, dest, OFPCML_NO_BUFFER ); openflow_instructions *insts4 = create_instructions(); append_instructions_apply_actions( insts4, actions4 ); buffer *flow_mod4 = create_flow_mod( get_transaction_id(), get_cookie(), 0, 0, OFPFC_ADD, 0, 0, OFP_HIGH_PRIORITY, OFP_NO_BUFFER, 0, 0, OFPFF_SEND_FLOW_REM, match4, insts4 ); send_openflow_message( datapath_id, flow_mod4); free_buffer( flow_mod4 ); delete_oxm_matches( match4 ); delete_instructions( insts4 ); info("done sending"); }
static void append_action( openflow_actions *actions, VALUE action ) { if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::Enqueue" ) ) == Qtrue ) { uint32_t queue_id = ( uint32_t ) NUM2UINT( rb_funcall( action, rb_intern( "queue_id" ), 0 ) ); uint16_t port_number = ( uint16_t ) NUM2UINT( rb_funcall( action, rb_intern( "port_number" ), 0 ) ); append_action_enqueue( actions, port_number, queue_id ); } else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SendOutPort" ) ) == Qtrue ) { uint16_t port_number = ( uint16_t ) NUM2UINT( rb_funcall( action, rb_intern( "port_number" ), 0 ) ); uint16_t max_len = ( uint16_t ) NUM2UINT( rb_funcall( action, rb_intern( "max_len" ), 0 ) ); append_action_output( actions, port_number, max_len ); } else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetEthDstAddr" ) ) == Qtrue ) { uint8_t dl_dst[ OFP_ETH_ALEN ]; uint8_t *ptr = ( uint8_t * ) dl_addr_to_a( rb_funcall( action, rb_intern( "mac_address" ), 0 ), dl_dst ); append_action_set_dl_dst( actions, ptr ); } else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetEthSrcAddr" ) ) == Qtrue ) { uint8_t dl_src[ OFP_ETH_ALEN ]; uint8_t *ptr = ( uint8_t * ) dl_addr_to_a( rb_funcall( action, rb_intern( "mac_address" ), 0 ), dl_src ); append_action_set_dl_src( actions, ptr ); } else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetIpDstAddr" ) ) == Qtrue ) { append_action_set_nw_dst( actions, nw_addr_to_i( rb_funcall( action, rb_intern( "ip_address" ), 0 ) ) ); } else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetIpSrcAddr" ) ) == Qtrue ) { append_action_set_nw_src( actions, nw_addr_to_i( rb_funcall( action, rb_intern( "ip_address" ), 0 ) ) ); } else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetIpTos" ) ) == Qtrue ) { append_action_set_nw_tos( actions, ( uint8_t ) NUM2UINT( rb_funcall( action, rb_intern( "type_of_service" ), 0 ) ) ); } else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetTransportDstPort" ) ) == Qtrue ) { append_action_set_tp_dst( actions, ( uint16_t ) NUM2UINT( rb_funcall( action, rb_intern( "port_number" ), 0 ) ) ); } else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetTransportSrcPort" ) ) == Qtrue ) { append_action_set_tp_src( actions, ( uint16_t ) NUM2UINT( rb_funcall( action, rb_intern( "port_number" ), 0 ) ) ); } else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetVlanPriority" ) ) == Qtrue ) { append_action_set_vlan_pcp( actions, ( uint8_t ) NUM2UINT( rb_funcall( action, rb_intern( "vlan_priority" ), 0 ) ) ); } else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::SetVlanVid" ) ) == Qtrue ) { append_action_set_vlan_vid( actions, ( uint16_t ) NUM2UINT( rb_funcall( action, rb_intern( "vlan_id" ), 0 ) ) ); } else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::StripVlanHeader" ) ) == Qtrue ) { append_action_strip_vlan( actions ); } else if ( rb_funcall( action, rb_intern( "is_a?" ), 1, rb_path2class( "Trema::VendorAction" ) ) == Qtrue ) { VALUE vendor_id = rb_funcall( action, rb_intern( "vendor_id" ), 0 ); VALUE rbody = rb_funcall( action, rb_intern( "body" ), 0 ); if ( rbody != Qnil ) { Check_Type( rbody, T_ARRAY ); uint16_t length = ( uint16_t ) RARRAY_LEN( rbody ); buffer *body = alloc_buffer_with_length( length ); void *p = append_back_buffer( body, length ); for ( int i = 0; i < length; i++ ) { ( ( uint8_t * ) p )[ i ] = ( uint8_t ) FIX2INT( RARRAY_PTR( rbody )[ i ] ); } append_action_vendor( actions, ( uint32_t ) NUM2UINT( vendor_id ), body ); free_buffer( body ); } else { append_action_vendor( actions, ( uint32_t ) NUM2UINT( vendor_id ), NULL ); } } else { rb_raise( rb_eTypeError, "actions argument must be an Array of Action objects" ); } }