Esempio n. 1
0
def _parse_snoop_status(is_igmp, vlan_id, data, vlan_name, event_data):

    ret = True
    event_data.update({'vlan-id': vlan_id, 'enable': data})

    ret = snoop_update_vlan_rules(is_igmp, vlan_name, data)
    if ret is False:
        mcast_utils.log_err(
            'Failed to %s ebtable snooping rules in kernel for %s ' %
            ("Add" if data == 1 else "Remove", vlan_name))
        return False

    mcast_utils.log_info('%s ebtable snooping rules in kernel for %s success' %
                         ("Add" if data == 1 else "Remove", vlan_name))

    # Disable snooping in kernel.
    ret = mcast_utils._update_file_system(
        mcast_utils._get_path_per_vlan_configs(vlan_name,
                                               "multicast_snooping"), 0)
    if ret is False:
        #When VLAN/bridge gets created,snooping will be disabled, this is just extra .
        mcast_utils.log_debug('Failed to disable snooping on %s in kernel' %
                              (vlan_name))

    return True
Esempio n. 2
0
def _parse_mcast_snoop_updates_and_publish(data, vlan_info, vlan_id,
                                           igmp_events, op):

    #Parse status, mrouter and route update and publish.
    vlan_name = vlan_info['cps/key_data']['if/interfaces/interface/name']
    try:
        for k in _snoop_obj_info:
            for path in _snoop_obj_info[k]['obj_path']:
                if path in data and _snoop_obj_info[k]['publish_events']:
                    # Publish CPS Events if required
                    event_data = {}
                    mcast_utils.log_info(
                        '%s %s %s for VLAN %d' %
                        ('IGMP' if igmp_events else 'MLD',
                         _snoop_obj_info[k]['event_string'], op, vlan_id))
                    if (k == 'static_l2_mcast_grp_key'):
                        if (_parse_snoop_routes(vlan_id, vlan_info, op,
                                                igmp_events, data[path],
                                                event_data)) is False:
                            return False
                    elif (k == 'static_mrouter_key'):
                        if (_parse_snoop_mrouter_ports(vlan_id, vlan_info, op,
                                                       data[path],
                                                       event_data)) is False:
                            return False
                    elif (k == 'mcast_snooping'):
                        if (_parse_snoop_status(igmp_events, vlan_id,
                                                data[path], vlan_name,
                                                event_data)) is False:
                            return False

                    obj = events.MCast_CpsEvents()
                    if event_data:
                        if igmp_events:
                            obj.publish_igmp_events(event_data, op)
                        else:
                            obj.publish_mld_events(event_data, op)

                        mcast_utils.log_info(
                            "Publishing %s %s %s event" %
                            (('IGMP ' if igmp_events else 'MLD '),
                             _snoop_obj_info[k]['event_string'], op))
                        mcast_utils.log_debug("Publish event data: %s" %
                                              (str(event_data)))

    except Exception as e:
        mcast_utils.log_err('Exception: %s' % e)

    return True
Esempio n. 3
0
def handle_snoop_updates(params):

    #This handles only the IGMP/MLD snooping "status", "mrouter port" and "route" updates.
    #This gets called only when kernel snooping functionality is not used and some snooping
    #application is running. This parses and publishes and does not set/update kernel for mrouter
    # and route updates.
    ret = True
    data = mcast_utils.cps_convert_attr_data(params['change'])

    mcast_utils.log_debug("Data: %s" % (str(data)))

    if mcast_utils.igmp_global_enable_key in data:
        return snoop_update_global_rules(
            True, data[mcast_utils.igmp_global_enable_key])
    elif mcast_utils.mld_global_enable_key in data:
        return snoop_update_global_rules(
            False, data[mcast_utils.mld_global_enable_key])

    if mcast_utils._keys['vlan_id_key'][
            'igmp'] not in data and mcast_utils._keys['vlan_id_key'][
                'mld'] not in data:
        mcast_utils.log_err("Missing VLAN ID")
        return False

    igmp_events = True
    if mcast_utils._keys['vlan_id_key']['igmp'] in data:
        vlan_id_key = mcast_utils._keys['vlan_id_key']['igmp']
    else:
        vlan_id_key = mcast_utils._keys['vlan_id_key']['mld']
        igmp_events = False

    vlan_id = data[vlan_id_key]

    mcast_utils.log_debug('%s Snoop update received for VLAN  %d' %
                          ('IGMP' if igmp_events else 'MLD', vlan_id))
    # Get dell-base-if-cmn/if/interfaces/interface object for the given vlan id
    vlan_info_list = mcast_utils._get_vlan_info(vlan_id)
    if vlan_info_list is None or len(vlan_info_list) == 0:
        mcast_utils.log_err('No VLAN Information for VLAN id %d' % vlan_id)
        return False
    vlan_info = vlan_info_list[0]

    ret = _parse_mcast_snoop_updates_and_publish(data, vlan_info, vlan_id,
                                                 igmp_events,
                                                 params['operation'])

    mcast_utils.log_debug('Finish processing snoop updates, ret=%d' % ret)
    return ret
Esempio n. 4
0
def monitor_VLAN_interface_event():
    _vlan_handle = cps.event_connect()
    cps.event_register(_vlan_handle, _intf_vlan_key)
    mcast_utils.log_info('monitor_VLAN_interface_event started')

    while True:
        vlan_event = cps.event_wait(_vlan_handle)
        obj = cps_object.CPSObject(obj=vlan_event)
        if obj is None:
            mcast_utils.log_err(
                'VLAN_MONITOR: Object not present in the event')
            continue
        if obj.get_key() != _intf_vlan_key:
            mcast_utils.log_debug(
                'VLAN_MONITOR: Wrong VLAN interface event, ignore')
            continue

        try:
            vlan_name = obj.get_attr_data('if/interfaces/interface/name')
            # check if if_name is present
            if vlan_name is None:
                mcast_utils.log_err(
                    'VLAN_MONITOR: VLAN name not present in the event')
                continue

            if 'operation' in vlan_event:
                mcast_utils.log_info('VLAN_MONITOR: Received %s %s event' %
                                     (vlan_name, vlan_event['operation']))
                if (vlan_event['operation'] == 'create'):
                    ret = mcast_utils._update_file_system(
                        mcast_utils._get_path_per_vlan_configs(
                            vlan_name, "multicast_snooping"), 0)
                    if ret is True:
                        mcast_utils.log_info(
                            'VLAN_MONITOR: Disabled snooping on %s in kernel' %
                            (vlan_name))
                    else:
                        mcast_utils.log_err(
                            'VLAN_MONITOR: Failed to disable snooping on %s in kernel'
                            % (vlan_name))
                elif (vlan_event['operation'] == 'delete'):
                    #On VLAN deletion, not sure application sends the snoop disable, even if it sends it comes
                    #with VLAN id, so for getting ifname NAS interface may not have VLAN and will fail to get name.
                    #and per VLAN rule in kernel may not get deleted. So here on VLAN deletion the per VLAN IGMP/MLD
                    #rules are deleted.
                    #
                    if (snoop_remove_vlan_rules(True, vlan_name)) is False:
                        mcast_utils.log_debug(
                            'VLAN_MONITOR: Failed to remove IGMP ebtables rule in kernel for %s'
                            % (vlan_name))
                    if (snoop_remove_vlan_rules(False, vlan_name)) is False:
                        mcast_utils.log_debug(
                            'VLAN_MONITOR: Failed to remove MLD ebtables rule in kernel for %s'
                            % (vlan_name))
            else:
                mcast_utils.log_info(
                    'VLAN_MONITOR: Received event without operation' %
                    (vlan_name))

        except Exception as e:
            mcast_utils.log_err('VLAN_MONITOR: Exception: %s' % e)
Esempio n. 5
0
def snoop_get_cb(methods, params):
    mcast_utils.log_debug('Snoop get not supported')
    return False
Esempio n. 6
0
def snoop_add_rule_chain(is_igmp):

    ret = True
    res = []

    mcast_utils.log_debug('Create chain: %d' % (is_igmp))
    #EBTABLES:
    #For each snoop disabled VLAN's, received IGMP/MLD packets are marked
    #and dropped in iptables raw table IGMPSNOOP/MLDSNOOP chain.
    # Here:
    #1. Create IGMPSNOOP/MLDSNOOP chain in iptables raw table to check the
    #   IGMP/MLD packet types and drop all the iGMP/MLD packets other than query
    #   for enabled VLANs. For enabled VLAN's snoop application will decide what
    #   to do with the packet.
    #2. Create a Rule in iptables raw table PREROUTING chain to catch
    #   marked (snooping enabled VLAN's) IGMP/MLD packets and redirect to
    #   IGMPSNOOOP/MLDSNOOP chain
    if is_igmp:
        ret = snoop_create_iptables_chain(is_igmp, 'raw', IGMP_CHAIN_NAME)
        if ret is False:
            mcast_utils.log_err(
                'Failed to create/add iptables rules to %s chain' %
                (IGMP_CHAIN_NAME))
            return ret

        # Add PREROUTING rule
        rule_prefix = 'iptables -t raw '
        cmd = (rule_prefix + ' -C ' + igmp_preroute_rule).split()
        if (mcast_utils.run_command(cmd, res) != 0):
            cmd = (rule_prefix + ' -A ' + igmp_preroute_rule).split()
            if (mcast_utils.run_command(cmd, res) != 0): ret = ret and False

        if ret is False:
            mcast_utils.log_err(
                'Failed to add iptables rules to PREROUTING chain')
            return ret

        #Add EBTABLES nat POSTROUTING IGMP rules
        ret = add_ebtable_rules(' nat ', ' POSTROUTING ',
                                igmp_global_ebtable_rule)

        if ret is False:
            mcast_utils.log_err(
                'Failed to add IGMP EBTABLE rules to nat POSTROUTING chain')
            return ret

        ret = snoop_bridge_nf_iptables_enable(is_igmp)
        if ret is False:
            mcast_utils.log_err('Failed to enable bridge_nf_call_iptables')
            return ret

    else:
        ret = snoop_create_iptables_chain(is_igmp, 'raw', MLD_CHAIN_NAME)
        if ret is False:
            mcast_utils.log_err(
                'Failed to create/add ip6tables rules to %s chain' %
                (MLD_CHAIN_NAME))
            return ret

        # Add PREROUTING rule
        rule_prefix = 'ip6tables -t raw '
        cmd = (rule_prefix + ' -C ' + mld_preroute_rule).split()
        if (mcast_utils.run_command(cmd, res) != 0):
            cmd = (rule_prefix + ' -A ' + mld_preroute_rule).split()
            if (mcast_utils.run_command(cmd, res) != 0): ret = ret and False

        if ret is False:
            mcast_utils.log_err(
                'Failed to add ip6tables rules to PREROUTING chain')
            return ret

        mcast_utils.log_debug('%s chain created and rules added succesfully' %
                              (IGMP_CHAIN_NAME if is_igmp else MLD_CHAIN_NAME))

        #Add EBTABLES nat POSTROUTING MLD rules
        ret = add_ebtable_rules(' nat ', ' POSTROUTING ',
                                mld_global_ebtable_rule)

        if ret is False:
            mcast_utils.log_err(
                'Failed to add MLD EBTABLE rules to nat POSTROUTING chain')
            return ret

        ret = snoop_bridge_nf_iptables_enable(is_igmp)
        if ret is False:
            mcast_utils.log_err('Failed to enable bridge_nf_call_ip6tables')
            return ret

    mcast_utils.log_info(
        'All %s global Ebtables/Iptables created and rules added succesfully' %
        ('IGMP' if is_igmp else 'MLD'))

    return ret
Esempio n. 7
0
def read_ebtable_rules(table, chain):
    cmd = ('ebtables -t ' + table + ' -L ' + chain).split()
    res = []
    mcast_utils.run_command(cmd, res)
    mcast_utils.log_debug("ebtable dump: %s" % (res))
    return res