Exemple #1
0
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;
}
Exemple #4
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 );
}
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 );
}
Exemple #6
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 ) {
  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 );
}
Exemple #8
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 );
}
Exemple #9
0
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 );
}
Exemple #10
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 );
}
Exemple #11
0
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 );
}
Exemple #12
0
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;
  }
}
Exemple #13
0
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 );
}
Exemple #15
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 );
}
Exemple #16
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 );
}
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 );
}
Exemple #20
0
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 );
}
Exemple #21
0
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");





}
Exemple #24
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 );

//  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");


}
Exemple #25
0
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" );
  }
}