def add_flow(flow, use_cache_ssh_con=True): """ Add a flow :param flow: OpenFlow string :param use_cache_ssh_con: whether or not to use a cached SSH connection (set to False when used in a thread) """ get_ssh_con_master(cached=use_cache_ssh_con).exec("sudo ovs-ofctl add-flow " + OVS_SWITCH_NAME + " " + flow, mayFail=False)
def delete_all_deployments(): """ Deletes all k8s deployments who's name contains KUBE_DEPLOYMENT_PREFIX TODO: Grep only when deployment starts with the prefix, not anywhere. Also append "-" to the prefix """ get_ssh_con_master().exec( "sudo kubectl delete deployment $(kubectl get deployments | cut -d' ' -f1 | grep " + KUBE_DEPLOYMENT_PREFIX + ")", mayFail=True)
def delete_deployment(deployment, use_cached_ssh_con=True): """ Delete deployment by it's details :param deployment: details as returned from create_deployment :param use_cached_ssh_con: whether or not to use a cached SSH connection (set to False when used in a thread) """ get_ssh_con_master(cached=use_cached_ssh_con).exec( "sudo kubectl delete deployment \"" + deployment["name"] + "\"", mayFail=False) dpdkr.add_free_port(deployment["dpdkr"]) # free dpdkr '''
def get_ovs_port_rxtx(): """ Get amount of rx/tx bytes/pkts/drop/errs per OpenFlow port Note: DPDK Rings always have "0" as byte count, so packet count must be used :return: dictionary {ovsPortNr: {"rx": {"pkts":,"drop":,"errs":}, "tx": {"pkts":,"drop":,"errs":}} } """ # Form: " port 123: rx pkts=1234, bytes=1234, drop=1234, errs=1234, ..." patternRx = re.compile("\s*port\s+(\d+): rx pkts=(\d+),.*?, drop=(\d+), errs=(\d+)") # Form: " tx pkts=1234, bytes=1234, drop=1234, errs=1234, ..." patternTx = re.compile("\s*tx pkts=(\d+),.*?, drop=(\d+), errs=(\d+)") ret_dict = {} # sometimes this command fails, so keep executing it untill it succeeds. lines = get_ssh_con_master().exec("sudo ovs-ofctl dump-ports " + OVS_SWITCH_NAME, asArray=True, mayFail=False, mustReturnOutput=True) Logger.log("Switch", "In get_ovs_port_rx_tx, lines = " + str(lines), 9) # loop over ssh output, match regex for i in range(0, len(lines)): matchRx = patternRx.match(lines[i]) if matchRx: matchTx = patternTx.match(lines[i+1]) ret_dict[int(matchRx.groups()[0])] = { "rx": { "pkts": int(matchRx.groups()[1]), "drop": int(matchRx.groups()[2]), "errs": int(matchRx.groups()[3]) }, "tx": { "pkts": int(matchTx.groups()[0]), "drop": int(matchTx.groups()[1]), "errs": int(matchTx.groups()[2]) } } return ret_dict
def get_ovs_to_dpdk_nr(): """ Get the OpenFlow port number to DPDK number mapping from the switch :return: dictionary {ovs:dpdk,...} """ # lines always are in the form " 123(dpdk12)...." pattern = re.compile("\s(\d+)\(dpdk(\d+)\)") ret_dict = {} for line in get_ssh_con_master().exec("sudo ovs-ofctl show " + OVS_SWITCH_NAME, asArray=True, mayFail=False): match = pattern.match(line) if match: ret_dict[match.groups()[0]] = int(match.groups()[1]) return ret_dict
def create_chain_flows(chain, deployments_per_component, is_incoming): """ Create all the flow rules for a single chain :param chain: List of component types. First element is the first component where the traffic enters, last component is the one where traffic exits :param deployments_per_component: list of deployments in a dictionary for each component :param is_incoming: whether this is an incoming or outgoing chain """ ssh_con = get_ssh_con_master() dpdk_to_ovs_nr = get_dpdk_to_ovs_nr() out_port = str(dpdk_to_ovs_nr[INTERNAL_DPDK_NR if is_incoming else EXTERNAL_DPDKR_NR]) # create flow from dpdk0 -> multipath first component -> before table from first component first_component = chain[0] Logger.log("Flow", "Creating flows for first component " + str(first_component), 4) ssh_con.exec("sudo ovs-ofctl add-flow " + OVS_SWITCH_NAME + " " + get_multipath_rule(chain, first_component, 1, is_incoming, dpdk_to_ovs_nr)) # before table from first component -> rings for this component ssh_con.exec("sudo ovs-ofctl add-flow " + OVS_SWITCH_NAME + " \"" "table=" + KUBE_COMPONENT_TO_OVS_CONFIG[first_component]["beforeTable"] + "," "reg" + KUBE_COMPONENT_TO_OVS_CONFIG[first_component]["register"] + "=0," "actions=output:" + str(deployments_per_component[first_component][0]["ovsPort"]) + "\"") # from the rings -> to the after table # ovs-ofctl add-flow br0 "in_port=2,actions=resubmit(,3)" ssh_con.exec("sudo ovs-ofctl add-flow " + OVS_SWITCH_NAME + " \"in_port=" + str( deployments_per_component[first_component][0]["ovsPort"]) + "," "actions=resubmit(," + KUBE_COMPONENT_TO_OVS_CONFIG[first_component]["afterTable"] + ")\"") prev_component = first_component for i in range(1, len(chain)): component = chain[i] Logger.log("Flow", "Creating flows for the next component " + str(component), 4) ssh_con.exec("sudo ovs-ofctl add-flow " + OVS_SWITCH_NAME + " " + get_multipath_rule(chain, component, 1, is_incoming, dpdk_to_ovs_nr)) # before table from component -> rings for this component ssh_con.exec("sudo ovs-ofctl add-flow " + OVS_SWITCH_NAME + " \"" "table=" + KUBE_COMPONENT_TO_OVS_CONFIG[component]["beforeTable"] + "," "reg" + KUBE_COMPONENT_TO_OVS_CONFIG[component]["register"] + "=0," "actions=output:" + str(deployments_per_component[component][0]["ovsPort"]) + "\"") # from the rings -> to the after table # ovs-ofctl add-flow br0 "in_port=2,actions=resubmit(,3)" ssh_con.exec("sudo ovs-ofctl add-flow " + OVS_SWITCH_NAME + " \"in_port=" + str( deployments_per_component[component][0]["ovsPort"]) + "," "actions=resubmit(," + KUBE_COMPONENT_TO_OVS_CONFIG[component]["afterTable"] + ")\"") prev_component = component check_vlan = "dl_vlan=" check_vlan += INCOMING_VLAN if is_incoming else OUTGOING_VLAN check_vlan += "," Logger.log("Flow", "Creating flow for last table to dpdk port", 4) ssh_con.exec("sudo ovs-ofctl add-flow " + OVS_SWITCH_NAME + " \"" "table=" + KUBE_COMPONENT_TO_OVS_CONFIG[prev_component]["afterTable"] + "," + check_vlan + "actions=strip_vlan,output:" + out_port + "\"")
def delete_flow(flow): """ Delete a flow :param flow: OpenFlow string """ get_ssh_con_master().exec("sudo ovs-ofctl del-flows " + OVS_SWITCH_NAME + " " + flow, mayFail=False)
def delete_all_flows(): """ Deletes all flows from the OVS switch """ get_ssh_con_master().exec("sudo ovs-ofctl del-flows " + OVS_SWITCH_NAME, mayFail=True)