static void
handle_desc_stats_reply( uint64_t datapath_id, uint32_t transaction_id,
                        uint16_t type, uint16_t flags, const buffer *data,
                       void *user_data ) {
  UNUSED( transaction_id );
  UNUSED( type );
  UNUSED( flags );
  show_desc *show_desc = user_data;

  if ( data->length < SIZE_OF_OFP_DESC ) {
    error( "invalid data" );

    stop_trema();
    return;
  }
  desc_entry *entry = xmalloc( sizeof( desc_entry ) );
  entry->datapath_id = datapath_id;
#ifdef TREMA_EDGE
  create_list( &entry->port_desc );
#endif
  memcpy( &entry->desc_stats, data->data, SIZE_OF_OFP_DESC );
  insert_hash_entry( show_desc->db, &entry->datapath_id, entry );

#ifdef TREMA_EDGE
  buffer *port_desc_request = create_port_desc_multipart_request( get_transaction_id(), 0 );
  send_openflow_message( datapath_id, port_desc_request );
  free_buffer( port_desc_request );
#else
  buffer *features_request = create_features_request( get_transaction_id() );
  send_openflow_message( datapath_id, features_request );
  free_buffer( features_request );
#endif
}
Example #2
0
File: fdb.c Project: mq24705/apps
static void
poison( uint64_t dpid, const uint8_t mac[ OFP_ETH_ALEN ] ) {
    struct ofp_match match;
    memset( &match, 0, sizeof( struct ofp_match ) );
    match.wildcards = ( OFPFW_ALL & ~OFPFW_DL_DST );
    memcpy( match.dl_dst, mac, OFP_ETH_ALEN );

    const uint16_t idle_timeout = 0;
    const uint16_t hard_timeout = 0;
    const uint16_t priority = 0;
    const uint32_t buffer_id = 0;
    const uint16_t flags = 0;
    buffer *flow_mod = create_flow_mod( get_transaction_id(), match, get_cookie(),
                                        OFPFC_DELETE, idle_timeout, hard_timeout,
                                        priority, buffer_id, OFPP_NONE, flags,
                                        NULL );
    send_openflow_message( dpid, flow_mod );
    free_buffer( flow_mod );

    memset( &match, 0, sizeof( struct ofp_match ) );
    match.wildcards = ( OFPFW_ALL & ~OFPFW_DL_SRC );
    memcpy( match.dl_src, mac, OFP_ETH_ALEN );
    flow_mod = create_flow_mod( get_transaction_id(), match, get_cookie(),
                                OFPFC_DELETE, idle_timeout, hard_timeout,
                                priority, buffer_id, OFPP_NONE, flags, NULL );
    send_openflow_message( dpid, flow_mod );
    free_buffer( flow_mod );

    debug( "Poisoning all entries whose dl_src or dl_dst matches %02x:%02x:%02x:%02x:%02x:%02x at dpid %#" PRIx64,
           mac[ 0 ], mac[ 1 ], mac[ 2 ], mac[ 3 ], mac[ 4 ], mac[ 5 ], dpid );

}
bool
execute_transaction( uint64_t datapath_id, const buffer *message,
                     succeeded_handler succeeded_callback, void *succeeded_user_data,
                     failed_handler failed_callback, void *failed_user_data ) {
  assert( message != NULL );
  assert( message->length >= sizeof( struct ofp_header ) );

  transaction_entry *entry = alloc_transaction_entry();

  entry->datapath_id = datapath_id;
  entry->message = duplicate_buffer( message );
  entry->xid = get_transaction_id();
  entry->barrier_xid = get_transaction_id();
  struct ofp_header *header = entry->message->data;
  entry->original_xid = ntohl( header->xid );
  header->xid = htonl( entry->xid ); // Override xid for keeping uniqueness
  entry->completed = false;
  entry->error_received = false;
  entry->timeout = false;

  debug( "Executing a transaction ( xid = %#x, barrier_xid = %#x, original_xid = %#x ).",
         entry->xid, entry->barrier_xid, entry->original_xid );

  bool ret = send_openflow_message( datapath_id, entry->message );
  if ( !ret ) {
    // FIXME: send queue may be full. We may need to retry for sending the message.
    error( "Failed to send an OpenFlow message ( datapath_id = %#" PRIx64 ", transaction_id = %#x ).",
           datapath_id, entry->original_xid );
    free_transaction_entry( entry );
    return false;
  }

  buffer *barrier = create_barrier_request( entry->barrier_xid );
  ret = send_openflow_message( datapath_id, barrier );
  free_buffer( barrier );
  if ( !ret ) {
    error( "Failed to send a barrier request ( datapath_id = %#" PRIx64 ", transaction_id = %#x ).",
           datapath_id, entry->barrier_xid );
    free_transaction_entry( entry );
    return false;
  }

  entry->succeeded_callback = succeeded_callback;
  entry->succeeded_user_data = succeeded_user_data;
  entry->failed_callback = failed_callback;
  entry->failed_user_data = failed_user_data;

  ret = add_transaction_entry( entry );
  if ( !ret ) {
    error( "Failed to save transaction entry ( %p ).", entry );
    dump_transaction_entry( error, entry );
    free_transaction_entry( entry );
    return false;
  }

  debug( "OpenFlow messages are put into a send queue and a transaction entry is saved." );

  return true;
}
Example #4
0
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
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 );
}
Example #6
0
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 );
}
Example #7
0
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, 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 );
}
Example #9
0
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 );
}
Example #10
0
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 );
}
Example #11
0
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;
}
Example #12
0
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 );
}
Example #13
0
/*
 * @overload send_message(datapath_id, message)
 *   Sends an OpenFlow message to the datapath.
 *
 *   @example
 *     send_message datapath_id, FeaturesRequest.new
 *
 *   @param [Integer] datapath_id
 *     the datapath to which a message is sent.
 *   @param [Hello, EchoRequest, EchoReply, FeaturesRequest, SetConfig, GetConfigRequest, QueueGetConfigRequest, StatsRequest, BarrierRequest, PortMod, Vendor] message
 *     the message to be sent.
 */
static VALUE
controller_send_message( VALUE self, VALUE datapath_id, VALUE message ) {
  buffer *buf;
  Data_Get_Struct( message, buffer, buf );
  send_openflow_message( NUM2ULL( datapath_id ), buf );
  return self;
}
static void
discard_packet_in( uint64_t datapath_id, uint16_t in_port, const buffer *packet ) {
  const uint32_t wildcards = 0;
  struct ofp_match match;
  set_match_from_packet( &match, in_port, wildcards, packet );
  char match_str[ 1024 ];
  match_to_string( &match, match_str, sizeof( match_str ) );

  const uint16_t idle_timeout = 0;
  const uint16_t hard_timeout = PACKET_IN_DISCARD_DURATION;
  const uint16_t priority = UINT16_MAX;
  const uint32_t buffer_id = UINT32_MAX;
  const uint16_t flags = 0;

  info( "Discarding packets for a certain period ( datapath_id = %#" PRIx64
        ", match = [%s], duration = %u [sec] ).", datapath_id, match_str, hard_timeout );

  buffer *flow_mod = create_flow_mod( get_transaction_id(), match, get_cookie(),
                                      OFPFC_ADD, idle_timeout, hard_timeout,
                                      priority, buffer_id,
                                      OFPP_NONE, flags, NULL );

  send_openflow_message( datapath_id, flow_mod );
  free_buffer( flow_mod );
}
Example #15
0
static void
handle_switch_ready( uint64_t datapath_id, void *user_data ) {
  UNUSED( user_data );

  buffer *message = create_features_request( get_transaction_id() );
  send_openflow_message( datapath_id, message );
  free_buffer( message );
}
Example #16
0
static void
send_features_request( sw_entry *sw ) {
  uint32_t id = get_transaction_id();
  buffer *buf = create_features_request( id );
  send_openflow_message( sw->datapath_id, buf );
  free_buffer( buf );
  debug( "Sent switch features request to %#" PRIx64 ".", sw->datapath_id );
}
Example #17
0
static void
handle_switch_ready( uint64_t datapath_id, void *user_data ) {
  UNUSED( user_data );

  uint32_t id = get_transaction_id();
  buffer *buf = create_features_request( id );
  send_openflow_message( datapath_id, buf );
  free_buffer( buf );
}
Example #18
0
static void
set_miss_send_len_maximum( uint64_t datapath_id ) {
  uint32_t id = get_transaction_id();
  const uint16_t config_flags = OFPC_FRAG_NORMAL;
  const uint16_t miss_send_len = UINT16_MAX;
  buffer *buf = create_set_config( id, config_flags, miss_send_len );
  send_openflow_message( datapath_id, buf );

  free_buffer( buf );
}
Example #19
0
static void
send_echo_requests( uint64_t datapath_id, void *count ) {
  for ( int i = 0; i < *( ( int * ) count ); i++ ) {
    buffer *echo_request = create_echo_request( get_transaction_id(), NULL );
    bool ret = send_openflow_message( datapath_id, echo_request );
    if ( !ret ) {
      error( "Failed to send an echo request message to the switch with datapath ID = %#" PRIx64 ".", datapath_id );
    }
    free_buffer( echo_request );
  }
}
Example #20
0
static void
send_hello( uint64_t datapath_id, void *count ) {
  for ( int i = 0; i < *( ( int * ) count ); i++ ) {
    buffer *hello = create_hello( get_transaction_id(), NULL );
    bool ret = send_openflow_message( datapath_id, hello );
    if ( !ret ) {
      error( "Failed to send an hello message to the switch with datapath ID = %#" PRIx64 ".", datapath_id );
    }
    free_buffer( hello );
  }
}
Example #21
0
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 );
}
Example #22
0
static void
send_features_request( uint64_t datapath_id, void *user_data ) {
  UNUSED( user_data );

  buffer *features_request = create_features_request( get_transaction_id() );
  bool ret = send_openflow_message( datapath_id, features_request );
  if ( !ret ) {
    error( "Failed to send a features request message to the switch with datapath ID = %#" PRIx64 ".", datapath_id );
    stop_trema();
  }
  free_buffer( features_request );
}
Example #23
0
static void
send_flow_mod_discarding_all_packets( sw_entry *sw, uint16_t hard_timeout, uint16_t priority ) {
  struct ofp_match match;
  memset( &match, 0, sizeof( struct ofp_match ) );
  match.wildcards = OFPFW_ALL;

  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, NULL );
  send_openflow_message( sw->datapath_id, flow_mod );
  free_buffer( flow_mod );
  debug( "Sent a flow_mod for discarding all packets received on %#" PRIx64 ".", sw->datapath_id );
}
Example #24
0
static void
send_packet_out( packet_in packet_in, openflow_actions *actions ) {
  buffer *frame = duplicate_buffer( packet_in.data );
  fill_ether_padding( frame );

  buffer *packet_out = create_packet_out(
    get_transaction_id(),
    UINT32_MAX,
    packet_in.in_port,
    actions,
    frame
  );

  free_buffer( frame );
  send_openflow_message( packet_in.datapath_id, packet_out );
  free_buffer( packet_out );
}
static void
delete_flows_of( uint64_t datapath_id, uint16_t port_no ) {
  struct ofp_match match;

  memset( &match, 0, sizeof( struct ofp_match ) );
  match.wildcards = OFPFW_ALL;
  buffer *flow_mod = create_flow_mod( get_transaction_id(), match, get_cookie(),
                                      OFPFC_DELETE, 0, 0, 0, 0, port_no, 0, NULL );
  send_openflow_message( datapath_id, flow_mod );
  free_buffer( flow_mod );

  memset( &match, 0, sizeof( struct ofp_match ) );
  match.wildcards = OFPFW_ALL;
  match.wildcards &= ( uint32_t ) ~OFPFW_IN_PORT;
  match.in_port = port_no;
  teardown_path_by_match( match );
}
Example #26
0
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
handle_list_switches_reply( const list_element *switches, void *user_data ) {
  show_desc *show_desc = user_data;

#ifdef TREMA_EDGE
  buffer *desc_stats_request = create_desc_multipart_request( get_transaction_id(), 0 );
#else
  buffer *desc_stats_request = create_desc_stats_request( get_transaction_id(), 0 );
#endif

  const list_element *element;
  for ( element = switches; element != NULL; element = element->next ) {
    uint64_t datapath_id = * ( uint64_t *) element->data;
    send_openflow_message( datapath_id, desc_stats_request );
    show_desc->count++;
  }

  free_buffer( desc_stats_request );
}
Example #28
0
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 );
}
Example #29
0
static void
send_packet_out_for_each_switch( switch_info *sw, buffer *packet, uint64_t dpid, uint16_t in_port ) {
  openflow_actions *actions = create_actions();
  int number_of_actions = foreach_port( sw->ports, build_packet_out_actions, actions, dpid, in_port );

  // check if no action is build
  if ( number_of_actions > 0 ) {
    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( sw->dpid, packet_out );

    free_buffer( packet_out );
  }

  delete_actions( actions );
}
Example #30
0
static void
send_packet_out( uint64_t datapath_id, openflow_actions *actions, const buffer *original ) {
  const uint32_t transaction_id = get_transaction_id();
  const uint32_t buffer_id = UINT32_MAX;
  const uint16_t in_port = OFPP_NONE;
  buffer *copy = NULL;
  const buffer *packet = original;

  if ( original->length + ETH_FCS_LENGTH < ETH_MINIMUM_LENGTH ) {
    copy = duplicate_buffer( original );
    fill_ether_padding( copy );
    packet = copy;
  }
  buffer *packet_out = create_packet_out( transaction_id, buffer_id, in_port,
                                          actions, packet );

  send_openflow_message( datapath_id, packet_out );

  free_buffer( packet_out );
  if ( copy != NULL ) {
    free_buffer( copy );
  }
}