static void _handle_packet_out( const uint32_t transaction_id, uint32_t buffer_id, uint32_t in_port, const openflow_actions *actions, const buffer *frame, void *user_data ) { UNUSED( transaction_id ); struct protocol *protocol = user_data; action_list *ac_list = create_action_list(); if ( actions != NULL ) { for ( list_element *e = actions->list; e != NULL; e = e->next ) { struct ofp_action_header *ac_hdr = e->data; ac_list = assign_actions( ac_list, ac_hdr, ac_hdr->len ); } } buffer *duplicated = NULL; if ( frame != NULL && frame->length > 0 ) { duplicated = duplicate_buffer( frame ); } execute_packet_out( buffer_id, in_port, ac_list, duplicated ); wakeup_datapath( protocol ); delete_action_list( ac_list ); if ( duplicated != NULL ) { free_buffer( duplicated ); } }
static void handle_flow_mod_mod( const uint32_t transaction_id, const uint64_t cookie, const uint64_t cookie_mask, const uint8_t table_id, const uint16_t idle_timeout, const uint16_t hard_timeout, const uint16_t priority, const uint32_t buffer_id, const uint16_t flags, const oxm_matches *oxm, const openflow_instructions *instructions, const bool strict, struct protocol *protocol ) { match *match = create_match( ); if ( oxm != NULL && oxm->n_matches > 0 ) { for ( list_element *e = oxm->list; e != NULL; e = e->next ) { oxm_match_header *hdr = e->data; assign_match( match, hdr ); } } instruction_set *ins_set = create_instruction_set(); if ( instructions != NULL ) { OFDPE ret = assign_instructions( ins_set, instructions->list ); if ( ret != OFDPE_SUCCESS ) { send_error_message( transaction_id, OFPET_FLOW_MOD_FAILED, OFPBIC_UNSUP_INST ); delete_instruction_set( ins_set ); delete_match( match ); return; } } OFDPE ret = update_or_add_flow_entry( table_id, match, cookie, cookie_mask, priority, idle_timeout, hard_timeout, flags, strict, ins_set ); delete_instruction_set( ins_set ); delete_match( match ); if ( ret != OFDPE_SUCCESS ) { uint16_t type = OFPET_FLOW_MOD_FAILED; uint16_t code = OFPFMFC_UNKNOWN; get_ofp_error( ret, &type, &code ); send_error_message( transaction_id, type, code ); return; } if ( buffer_id != OFP_NO_BUFFER ) { action_list *actions = create_action_list(); action *action = create_action_output( OFPP_TABLE, UINT16_MAX ); append_action( actions, action ); ret = execute_packet_out( buffer_id, 0, actions, NULL ); delete_action_list( actions ); if ( ret != OFDPE_SUCCESS ) { uint16_t type = OFPET_FLOW_MOD_FAILED; uint16_t code = OFPFMFC_UNKNOWN; get_ofp_error( ret, &type, &code ); send_error_message( transaction_id, type, code ); return; } wakeup_datapath( protocol ); } }
action_list * duplicate_action_list( action_list *list ) { if ( list == NULL ) { return NULL; } dlist_element *dst = create_action_list(); for ( dlist_element *element = get_first_element( list ); element != NULL; element = element->next ) { action *src_action = element->data; if ( src_action != NULL ) { action *dst_action = duplicate_action( src_action ); insert_before_dlist( dst, dst_action ); } } return dst; }
int check_action(char *str, t_action *action, t_pos *pos, t_ftab *ftab) { char **tab; t_action *new_action; int ret; if (!check_empty(str)) return (0); if (!(new_action = create_action_list()) || !(str = format_instruction(str)) || !(tab = cut_instruction(str)) || (ret = check_name(tab[0], new_action, pos)) == -1) return (1); if (ftab[ret] != NULL) { new_action->pos = 0; if (ftab[ret](new_action, tab[1], pos)) return (1); } add_action(action, new_action); return (0); }
void gtkparasite_window_create() { ParasiteWindow *window; GtkWidget *vpaned; GtkWidget *notebook; char *title; window = g_new0(ParasiteWindow, 1); /* * Create the top-level window. */ window->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size(GTK_WINDOW(window->window), 1000, 500); gtk_container_set_border_width(GTK_CONTAINER(window->window), 12); gtk_widget_show(window->window); title = g_strdup_printf("Parasite - %s", g_get_application_name()); gtk_window_set_title(GTK_WINDOW(window->window), title); g_free(title); vpaned = gtk_vpaned_new(); gtk_widget_show(vpaned); gtk_container_add(GTK_CONTAINER(window->window), vpaned); notebook = gtk_notebook_new(); gtk_widget_show(notebook); gtk_paned_pack1(GTK_PANED(vpaned), notebook, TRUE, FALSE); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), create_widget_tree(window), gtk_label_new("Widget Tree")); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), create_action_list(window), gtk_label_new("Action List")); if (parasite_python_is_enabled()) { GtkWidget *menuitem; window->python_shell = parasite_python_shell_new(); gtk_widget_show(window->python_shell); gtk_paned_pack2(GTK_PANED(vpaned), window->python_shell, FALSE, FALSE); /* * XXX Eventually we'll want to put more in here besides the menu * item we define below. At that point, we'll need to make this * more generic. */ window->widget_popup = gtk_menu_new(); gtk_widget_show(window->widget_popup); menuitem = gtk_menu_item_new_with_label("Send Widget to Shell"); gtk_widget_show(menuitem); gtk_menu_shell_append(GTK_MENU_SHELL(window->widget_popup), menuitem); g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(on_send_widget_to_shell_activate), window); gtkparasite_add_gtkbuilder_menu(window); window->action_popup = gtk_menu_new(); gtk_widget_show(window->action_popup); menuitem = gtk_menu_item_new_with_label("Send Object to Shell"); gtk_widget_show(menuitem); gtk_menu_shell_append(GTK_MENU_SHELL(window->action_popup), menuitem); g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(on_send_action_to_shell_activate), window); } else { window->widget_popup = gtk_menu_new(); gtk_widget_show(window->widget_popup); gtkparasite_add_gtkbuilder_menu(window); } }
static void handle_flow_mod_add( const uint32_t transaction_id, const uint64_t cookie, const uint64_t cookie_mask, const uint8_t table_id, const uint16_t idle_timeout, const uint16_t hard_timeout, const uint16_t priority, const uint32_t buffer_id, const uint16_t flags, const oxm_matches *oxm, const openflow_instructions *instructions, struct protocol *protocol ) { UNUSED( cookie_mask ); /* * currently if flags set OFPFF_SEND_FLOW_REM and OFPFF_RESET_COUNTS are the only allowed value. */ if ( ( flags & ~( OFPFF_SEND_FLOW_REM | OFPFF_RESET_COUNTS ) ) != 0 ) { send_error_message( transaction_id, OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_FLAGS ); return; } /* * The use of OFPTT_ALL is only valid for delete requests. */ if ( table_id == OFPTT_ALL ) { send_error_message( transaction_id, OFPET_FLOW_MOD_FAILED, OFPFMFC_BAD_TABLE_ID ); return; } /* * If no buffered packet is associated with a flow mod it must be set * to OFP_NO_BUFFER otherwise it must be equal to the buffer_id sent to * controller by a packet-in message. */ match *match = create_match(); if ( oxm != NULL && oxm->n_matches > 0 ) { #ifdef DEBUG char oxm_str[ 2048 ]; match_to_string( oxm, oxm_str, sizeof( oxm_str ) ); printf( "%s\n", oxm_str ); #endif for ( list_element *e = oxm->list; e != NULL; e = e->next ) { oxm_match_header *hdr = e->data; assign_match( match, hdr ); } } instruction_set *instruction_set = create_instruction_set(); if ( instructions != NULL ) { OFDPE ret = assign_instructions( instruction_set, instructions->list ); if ( ret != OFDPE_SUCCESS ) { send_error_message( transaction_id, OFPET_FLOW_MOD_FAILED, OFPBIC_UNSUP_INST ); delete_instruction_set( instruction_set ); delete_match( match ); return; } } /* * When a flow entry is inserted in a table, its flags field is set with the * values from the message. * When a flow entry is inserted in a table, its idle_timeout and * hard_timeout fields are set with the values from the message. * When a flow entry is inserted in a table through an OFPFC_ADD message, * its cookie field is set to the provided value */ flow_entry *new_entry = alloc_flow_entry( match, instruction_set, priority, idle_timeout, hard_timeout, flags, cookie ); if ( new_entry == NULL ) { /* * TODO we should send a more appropriate error once we worked out the * datapath errors. */ delete_instruction_set( instruction_set ); delete_match( match ); send_error_message( transaction_id, OFPET_FLOW_MOD_FAILED, OFPFMFC_UNKNOWN ); return; } OFDPE ret = add_flow_entry( table_id, new_entry, flags ); if ( ret != OFDPE_SUCCESS ) { error( "Failed to add a flow entry ( ret = %d ).", ret ); delete_instruction_set( instruction_set ); delete_match( match ); uint16_t type = OFPET_FLOW_MOD_FAILED; uint16_t code = OFPFMFC_UNKNOWN; get_ofp_error( ret, &type, &code ); send_error_message( transaction_id, type, code ); return; } if ( buffer_id != OFP_NO_BUFFER ) { action_list *actions = create_action_list(); action *action = create_action_output( OFPP_TABLE, UINT16_MAX ); append_action( actions, action ); ret = execute_packet_out( buffer_id, 0, actions, NULL ); delete_action_list( actions ); if ( ret != OFDPE_SUCCESS ) { uint16_t type = OFPET_FLOW_MOD_FAILED; uint16_t code = OFPFMFC_UNKNOWN; get_ofp_error( ret, &type, &code ); send_error_message( transaction_id, type, code ); return; } wakeup_datapath( protocol ); } }