X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=datapath%2Fforward.c;h=7e987e338cf79c46fe29ee1e3ab0cd05d2e7b297;hb=6f8d45bf7dd4007410f42f7233243cff409d06c6;hp=65a98aebc4eb3b10a3022892084bbfcad283f027;hpb=bbbc6bc992fbc018e2d1960a65088ffe70312256;p=openvswitch diff --git a/datapath/forward.c b/datapath/forward.c index 65a98aeb..7e987e33 100644 --- a/datapath/forward.c +++ b/datapath/forward.c @@ -41,7 +41,8 @@ void fwd_port_input(struct sw_chain *chain, struct sk_buff *skb, int in_port) flow->actions, flow->n_actions); } else { dp_output_control(chain->dp, skb, fwd_save_skb(skb), - chain->dp->miss_send_len, OFPR_NO_MATCH); + ntohs(chain->dp->config.miss_send_len), + OFPR_NO_MATCH); } } @@ -256,25 +257,31 @@ struct sk_buff *execute_setter(struct sk_buff *skb, uint16_t eth_proto, } static int -recv_control_hello(struct sw_chain *chain, const void *msg) +recv_features_request(struct sw_chain *chain, const struct sender *sender, + const void *msg) { - const struct ofp_control_hello *och = msg; - - printk("control_hello(version=%d)\n", ntohl(och->version)); - - if (ntohs(och->miss_send_len) != OFP_MISS_SEND_LEN_UNCHANGED) { - chain->dp->miss_send_len = ntohs(och->miss_send_len); - } - - chain->dp->hello_flags = ntohs(och->flags); + return dp_send_features_reply(chain->dp, sender); +} - dp_send_hello(chain->dp); +static int +recv_get_config_request(struct sw_chain *chain, const struct sender *sender, + const void *msg) +{ + return dp_send_config_reply(chain->dp, sender); +} +static int +recv_set_config(struct sw_chain *chain, const struct sender *sender, + const void *msg) +{ + const struct ofp_switch_config *osc = msg; + chain->dp->config = *osc; return 0; } static int -recv_packet_out(struct sw_chain *chain, const void *msg) +recv_packet_out(struct sw_chain *chain, const struct sender *sender, + const void *msg) { const struct ofp_packet_out *opo = msg; struct sk_buff *skb; @@ -322,7 +329,8 @@ recv_packet_out(struct sw_chain *chain, const void *msg) } static int -recv_port_mod(struct sw_chain *chain, const void *msg) +recv_port_mod(struct sw_chain *chain, const struct sender *sender, + const void *msg) { const struct ofp_port_mod *opm = msg; @@ -406,7 +414,7 @@ error: } static int -recv_flow(struct sw_chain *chain, const void *msg) +recv_flow(struct sw_chain *chain, const struct sender *sender, const void *msg) { const struct ofp_flow_mod *ofm = msg; uint16_t command = ntohs(ofm->command); @@ -426,21 +434,58 @@ recv_flow(struct sw_chain *chain, const void *msg) } } -/* 'msg', which is 'length' bytes long, was received from the control path. - * Apply it to 'chain'. */ +static int +recv_flow_status_request(struct sw_chain *chain, const struct sender *sender, + const void *msg) +{ + const struct ofp_flow_stat_request *fsr = msg; + if (fsr->type == OFPFS_INDIV) { + return dp_send_flow_stats(chain->dp, sender, &fsr->match); + } else { + /* FIXME */ + return -ENOTSUPP; + } +} + +static int +recv_port_status_request(struct sw_chain *chain, const struct sender *sender, + const void *msg) +{ + return dp_send_port_stats(chain->dp, sender); +} + +static int +recv_table_status_request(struct sw_chain *chain, const struct sender *sender, + const void *msg) +{ + return dp_send_table_stats(chain->dp, sender); +} + +/* 'msg', which is 'length' bytes long, was received across Netlink from + * 'sender'. Apply it to 'chain'. */ int -fwd_control_input(struct sw_chain *chain, const void *msg, size_t length) +fwd_control_input(struct sw_chain *chain, const struct sender *sender, + const void *msg, size_t length) { struct openflow_packet { size_t min_size; - int (*handler)(struct sw_chain *, const void *); + int (*handler)(struct sw_chain *, const struct sender *, + const void *); }; static const struct openflow_packet packets[] = { - [OFPT_CONTROL_HELLO] = { - sizeof (struct ofp_control_hello), - recv_control_hello, + [OFPT_FEATURES_REQUEST] = { + sizeof (struct ofp_header), + recv_features_request, + }, + [OFPT_GET_CONFIG_REQUEST] = { + sizeof (struct ofp_header), + recv_get_config_request, + }, + [OFPT_SET_CONFIG] = { + sizeof (struct ofp_switch_config), + recv_set_config, }, [OFPT_PACKET_OUT] = { sizeof (struct ofp_packet_out), @@ -454,14 +499,23 @@ fwd_control_input(struct sw_chain *chain, const void *msg, size_t length) sizeof (struct ofp_port_mod), recv_port_mod, }, + [OFPT_FLOW_STAT_REQUEST] = { + sizeof (struct ofp_flow_stat_request), + recv_flow_status_request, + }, + [OFPT_PORT_STAT_REQUEST] = { + sizeof (struct ofp_port_stat_request), + recv_port_status_request, + }, + [OFPT_TABLE_STAT_REQUEST] = { + sizeof (struct ofp_table_stat_request), + recv_table_status_request, + }, }; const struct openflow_packet *pkt; struct ofp_header *oh; - if (length < sizeof(struct ofp_header)) - return -EINVAL; - oh = (struct ofp_header *) msg; if (oh->version != 1 || oh->type >= ARRAY_SIZE(packets) || ntohs(oh->length) > length) @@ -473,7 +527,7 @@ fwd_control_input(struct sw_chain *chain, const void *msg, size_t length) if (length < pkt->min_size) return -EFAULT; - return pkt->handler(chain, msg); + return pkt->handler(chain, sender, msg); } /* Packet buffering. */