From 27732ac40cec08729eaad6551ef0e3f61547563e Mon Sep 17 00:00:00 2001 From: "bschanmu@redhat.com" Date: Tue, 24 Nov 2015 16:49:00 +0530 Subject: [PATCH] ovn: Dedicated connection handler for packet-ins This patch opens and maintains a new connection that is dedicated to monitor the packet-ins for br-int. Signed-off-by: Babu Shanmugam [blp@nicira.com removed support for OpenFlow 1.0] Signed-off-by: Ben Pfaff --- AUTHORS | 1 + ovn/controller/automake.mk | 2 + ovn/controller/ovn-controller.c | 6 ++ ovn/controller/pinctrl.c | 173 ++++++++++++++++++++++++++++++++ ovn/controller/pinctrl.h | 34 +++++++ 5 files changed, 216 insertions(+) create mode 100644 ovn/controller/pinctrl.c create mode 100644 ovn/controller/pinctrl.h diff --git a/AUTHORS b/AUTHORS index 02f7f1a98..7d9ea9070 100644 --- a/AUTHORS +++ b/AUTHORS @@ -26,6 +26,7 @@ Ariel Tubaltsev atubaltsev@vmware.com Arun Sharma arun.sharma@calsoftinc.com Aryan TaheriMonfared aryan.taherimonfared@uis.no Ashwin Swaminathan ashwinds@arista.com +Babu Shanmugam bschanmu@redhat.com Ben Pfaff blp@ovn.org Bert Vermeulen bert@biot.com Billy O'Mahony billy.o.mahony@intel.com diff --git a/ovn/controller/automake.mk b/ovn/controller/automake.mk index fec9bf17b..cadfa9cd5 100644 --- a/ovn/controller/automake.mk +++ b/ovn/controller/automake.mk @@ -10,6 +10,8 @@ ovn_controller_ovn_controller_SOURCES = \ ovn/controller/lflow.h \ ovn/controller/ofctrl.c \ ovn/controller/ofctrl.h \ + ovn/controller/pinctrl.c \ + ovn/controller/pinctrl.h \ ovn/controller/patch.c \ ovn/controller/patch.h \ ovn/controller/ovn-controller.c \ diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 3f29b257f..02ecb3ee3 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -41,6 +41,7 @@ #include "util.h" #include "ofctrl.h" +#include "pinctrl.h" #include "binding.h" #include "chassis.h" #include "encaps.h" @@ -223,6 +224,7 @@ main(int argc, char *argv[]) sbrec_init(); ofctrl_init(); + pinctrl_init(); lflow_init(); /* Connect to OVS OVSDB instance. We do not monitor all tables by @@ -292,6 +294,8 @@ main(int argc, char *argv[]) if (br_int) { enum mf_field_id mff_ovn_geneve = ofctrl_run(br_int); + pinctrl_run(&ctx, br_int); + struct hmap flow_table = HMAP_INITIALIZER(&flow_table); lflow_run(&ctx, &flow_table, &ct_zones); if (chassis_id) { @@ -314,6 +318,7 @@ main(int argc, char *argv[]) if (br_int) { ofctrl_wait(); + pinctrl_wait(); } poll_block(); if (should_service_stop()) { @@ -351,6 +356,7 @@ main(int argc, char *argv[]) unixctl_server_destroy(unixctl); lflow_destroy(); ofctrl_destroy(); + pinctrl_destroy(); simap_destroy(&ct_zones); diff --git a/ovn/controller/pinctrl.c b/ovn/controller/pinctrl.c new file mode 100644 index 000000000..8c53c195c --- /dev/null +++ b/ovn/controller/pinctrl.c @@ -0,0 +1,173 @@ + +/* Copyright (c) 2015 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "dirs.h" +#include "pinctrl.h" +#include "ofp-msgs.h" +#include "ofp-print.h" +#include "ofp-util.h" +#include "rconn.h" +#include "openvswitch/vlog.h" +#include "socket-util.h" +#include "vswitch-idl.h" + +VLOG_DEFINE_THIS_MODULE(pinctrl); + +/* OpenFlow connection to the switch. */ +static struct rconn *swconn; + +/* Last seen sequence number for 'swconn'. When this differs from + * rconn_get_connection_seqno(rconn), 'swconn' has reconnected. */ +static unsigned int conn_seq_no; + +void +pinctrl_init(void) +{ + swconn = rconn_create(5, 0, DSCP_DEFAULT, 1 << OFP13_VERSION); + conn_seq_no = 0; +} + +static ovs_be32 +queue_msg(struct ofpbuf *msg) +{ + const struct ofp_header *oh = msg->data; + ovs_be32 xid = oh->xid; + + rconn_send(swconn, msg, NULL); + return xid; +} + +static void +get_switch_config(struct rconn *swconn) +{ + struct ofpbuf *request; + + request = ofpraw_alloc(OFPRAW_OFPT_GET_CONFIG_REQUEST, + rconn_get_version(swconn), 0); + queue_msg(request); +} + +static void +set_switch_config(struct rconn *swconn, const struct ofp_switch_config *config) +{ + struct ofpbuf *request; + + request = + ofpraw_alloc(OFPRAW_OFPT_SET_CONFIG, rconn_get_version(swconn), 0); + ofpbuf_put(request, config, sizeof *config); + + queue_msg(request); +} + +static void +process_packet_in(struct controller_ctx *ctx OVS_UNUSED, + const struct ofp_header *msg) +{ + struct ofputil_packet_in pin; + + if (ofputil_decode_packet_in(&pin, msg) != 0) { + return; + } + if (pin.reason != OFPR_ACTION) { + return; + } + + /* XXX : process the received packet */ +} + +static void +pinctrl_recv(struct controller_ctx *ctx, const struct ofp_header *oh, + enum ofptype type) +{ + if (type == OFPTYPE_ECHO_REQUEST) { + queue_msg(make_echo_reply(oh)); + } else if (type == OFPTYPE_GET_CONFIG_REPLY) { + struct ofpbuf rq_buf; + struct ofp_switch_config *config_, config; + + ofpbuf_use_const(&rq_buf, oh, ntohs(oh->length)); + config_ = ofpbuf_pull(&rq_buf, sizeof *config_); + config = *config_; + config.miss_send_len = htons(UINT16_MAX); + set_switch_config(swconn, &config); + } else if (type == OFPTYPE_PACKET_IN) { + process_packet_in(ctx, oh); + } else if (type != OFPTYPE_ECHO_REPLY && type != OFPTYPE_BARRIER_REPLY) { + if (VLOG_IS_DBG_ENABLED()) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(30, 300); + + char *s = ofp_to_string(oh, ntohs(oh->length), 2); + + VLOG_DBG_RL(&rl, "OpenFlow packet ignored: %s", s); + free(s); + } + } +} + +void +pinctrl_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int) +{ + if (br_int) { + char *target; + + target = xasprintf("unix:%s/%s.mgmt", ovs_rundir(), br_int->name); + if (strcmp(target, rconn_get_target(swconn))) { + VLOG_INFO("%s: connecting to switch", target); + rconn_connect(swconn, target, target); + } + free(target); + } else { + rconn_disconnect(swconn); + } + + rconn_run(swconn); + + if (!rconn_is_connected(swconn)) { + return; + } + + if (conn_seq_no != rconn_get_connection_seqno(swconn)) { + get_switch_config(swconn); + conn_seq_no = rconn_get_connection_seqno(swconn); + } + + struct ofpbuf *msg = rconn_recv(swconn); + + if (!msg) { + return; + } + + const struct ofp_header *oh = msg->data; + enum ofptype type; + + ofptype_decode(&type, oh); + pinctrl_recv(ctx, oh, type); + ofpbuf_delete(msg); +} + +void +pinctrl_wait(void) +{ + rconn_run_wait(swconn); + rconn_recv_wait(swconn); +} + +void +pinctrl_destroy(void) +{ + rconn_destroy(swconn); +} diff --git a/ovn/controller/pinctrl.h b/ovn/controller/pinctrl.h new file mode 100644 index 000000000..65d5dfed9 --- /dev/null +++ b/ovn/controller/pinctrl.h @@ -0,0 +1,34 @@ + +/* Copyright (c) 2015 Nicira, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DHCP_H +#define DHCP_H 1 + +#include + +#include "meta-flow.h" + +struct ovsrec_bridge; +struct controller_ctx; + +/* Interface for OVN main loop. */ +void pinctrl_init(void); +void pinctrl_run(struct controller_ctx *ctx, + const struct ovsrec_bridge *br_int); +void pinctrl_wait(void); +void pinctrl_destroy(void); + +#endif /* ovn/dhcp.h */ -- 2.20.1