#!/usr/bin/env python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.

# A simple script for enabling and disabling per-vif and tunnel interface rules for explicitly
# allowing broadcast/multicast traffic from the tunnel ports and on the port where the VIF is attached

import copy
import os
import sys
import logging

import cloudstack_pluginlib as pluginlib

pluginlib.setup_logging("/var/log/cloud/ovstunnel.log")

def clear_flows(bridge, this_vif_ofport, vif_ofports):
    action = "".join("output:%s," %ofport
                     for ofport in vif_ofports)[:-1]
    # Remove flow entries originating from given ofport
    pluginlib.del_flows(bridge, in_port=this_vif_ofport)
    # The following will remove the port being delete from actions
    pluginlib.add_flow(bridge, priority=1100,
                       dl_dst='ff:ff:ff:ff:ff:ff', actions=action)
    pluginlib.add_flow(bridge, priority=1100,
                       nw_dst='224.0.0.0/24', actions=action)


def apply_flows(bridge, this_vif_ofport, vif_ofports):
    action = "".join("output:%s," %ofport
                     for ofport in vif_ofports)[:-1]
    # Ensure {b|m}casts sent from VIF ports are always allowed
    pluginlib.add_flow(bridge, priority=1200,
                       in_port=this_vif_ofport,
                       dl_dst='ff:ff:ff:ff:ff:ff',
                       actions='NORMAL')
    pluginlib.add_flow(bridge, priority=1200,
                       in_port=this_vif_ofport,
                       nw_dst='224.0.0.0/24',
                       actions='NORMAL')
    # Ensure {b|m}casts are always propagated to VIF ports
    pluginlib.add_flow(bridge, priority=1100,
                       dl_dst='ff:ff:ff:ff:ff:ff', actions=action)
    pluginlib.add_flow(bridge, priority=1100,
                       nw_dst='224.0.0.0/24', actions=action)

def clear_rules(vif):
    try:
        delcmd = "/sbin/ebtables -t nat -L PREROUTING | grep " + vif
        delcmds = pluginlib.do_cmd(['/bin/bash', '-c', delcmd]).split('\n')
        for cmd in delcmds:
            try:
                cmd = '/sbin/ebtables -t nat -D PREROUTING ' + cmd
                pluginlib.do_cmd(['/bin/bash', '-c', cmd])
            except:
                pass
    except:
        pass

def main(command, vif_raw):
    if command not in ('online', 'offline'):
        return

    vif_name, dom_id, vif_index = vif_raw.split('-')
    # validate vif and dom-id
    this_vif = "%s%s.%s" % (vif_name, dom_id, vif_index)
    # Make sure the networking stack is not linux bridge!
    net_stack = pluginlib.do_cmd(['cat', '/etc/xensource/network.conf'])
    if net_stack.lower() == "bridge":
        if command == 'offline':
            clear_rules(this_vif)
        # Nothing to do here!
        return

    bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'iface-to-br', this_vif])

    # find xs network for this bridge, verify is used for ovs tunnel network
    xs_nw_uuid = pluginlib.do_cmd([pluginlib.XE_PATH, "network-list",
                                   "bridge=%s" % bridge, "--minimal"])

    ovs_tunnel_network = pluginlib.is_regular_tunnel_network(xs_nw_uuid)

    # handle case where network is reguar tunnel network
    if ovs_tunnel_network == 'True':
        vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge])
        if vlan != '0':
            # We need the REAL bridge name
            bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
                                       'br-to-parent', bridge])
        vsctl_output = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
                                         'list-ports', bridge])
        vifs = vsctl_output.split('\n')
        vif_ofports = []
        vif_other_ofports = []
        for vif in vifs:
            vif_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get',
                                           'Interface', vif, 'ofport'])
            if this_vif == vif:
                this_vif_ofport = vif_ofport
            if vif.startswith('vif'):
                vif_ofports.append(vif_ofport)

        if command == 'offline':
            vif_other_ofports = copy.copy(vif_ofports)
            vif_other_ofports.remove(this_vif_ofport)
            clear_flows(bridge,  this_vif_ofport, vif_other_ofports)

        if command == 'online':
            apply_flows(bridge,  this_vif_ofport, vif_ofports)


    # handle case where bridge is setup for VPC which is enabled for distributed routing
    ovs_vpc_distributed_vr_network = pluginlib.is_vpc_network_with_distributed_routing(xs_nw_uuid)
    if ovs_vpc_distributed_vr_network == 'True':
        vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge])
        if vlan != '0':
            # We need the REAL bridge name
            bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
                                       'br-to-parent', bridge])
        vif_network_id = pluginlib.get_network_id_for_vif(this_vif)
        pluginlib.update_flooding_rules_on_port_plug_unplug(bridge, this_vif, command, vif_network_id)

    return

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("usage: {} [online|offline] vif-domid-idx".format(os.path.basename(sys.argv[0])))
        sys.exit(1)
    else:
        command, vif_raw = sys.argv[1:3]
        main(command, vif_raw)
