Changeset 13618 in genesis for tools/gformat.py


Ignore:
Timestamp:
Aug 26, 2016, 9:43:15 AM (8 years ago)
Author:
rick
Message:

Re-do bridge configuration to support VLAN administation.

The current bridge implementation has limits when it comes to configuring
interfaces. Since a bridge member does not have an IP yet it has connected
interface (via an VLAN switch) thus this details needs to be stored.

It is also considered to be confusing, since bridge(4) interfaces do appea
even if you did not configure them, potentially changing configurations of all
current nodes as well, which makes testing and deployment an tricky business.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • tools/gformat.py

    r13617 r13618  
    216216        datadump[key]['autogen_vlan'] = False
    217217
    218         datadump[key]['autogen_gateway'] = datadump[key]['ip'].split('/')[0]
     218        datadump[key]['autogen_bridge_member'] = datadump[key].has_key('parent')
     219        datadump[key]['autogen_bridge'] = datadump[key]['autogen_ifbase'].startswith('bridge')
     220
     221        if datadump[key].has_key('ip'):
     222          datadump[key]['autogen_gateway'] = datadump[key]['ip'].split('/')[0]
     223
    219224        if datadump[key]['type'] in ['11a', '11b', '11g', 'wireless']:
    220225          datadump[key]['autogen_ifname'] = 'wlan%i' % wlan_count
     226          datadump[key]['autogen_iface'] = 'wlan%i' % wlan_count
    221227          wlan_count += 1
    222228        else:
     
    224230          if len(key.split('_')) > 2 and key.split('_')[2].isdigit():
    225231            datadump[key]['autogen_vlan'] = key.split('_')[2]
    226 
    227         datadump[key]['autogen_bridge'] = datadump[key]['autogen_ifbase'].startswith('bridge')
    228         if datadump[key]['autogen_bridge'] and not 'alias' in key:
    229           datadump[key]['autogen_bridge_interfaces'] = datadump[key]['members'].split()
     232            datadump[key]['autogen_iface'] = '.'.join(key.split('_')[1:])
     233          else:
     234            datadump[key]['autogen_iface'] = '_'.join(key.split('_')[1:])
     235
    230236    except Exception:
    231237      print "# Error while processing interface %s" % key
     
    522528      datadump[iface_key]['comment'] = None
    523529
    524     if dhcp_type(datadump[iface_key]) != DHCP_SERVER:
    525       dhcp_out[ifname].append("## %(autogen_ifname)s - %(comment)s\n" % datadump[iface_key])
    526     else:
    527       dhcp_out['bridge0'].append("   ## %(autogen_ifname)s - %(comment)s\n" % datadump[iface_key])
     530    if not datadump[iface_key].has_key('ip'):
     531      continue
     532
     533    dhcp_out[iface_key].append("## %(autogen_iface)s - %(comment)s\n" % datadump[iface_key])
    528534
    529535    (addr, mask) = datadump[iface_key]['ip'].split('/')
     
    533539
    534540    if dhcp_type(datadump[iface_key]) != DHCP_SERVER:
    535       dhcp_out[ifname].append(textwrap.dedent("""\
     541      dhcp_out[iface_key].append(textwrap.dedent("""\
    536542        subnet %(autogen_subnet)s netmask %(autogen_netmask)s {
    537543          ### not autoritive
     
    549555      fixed = 5
    550556      for mac in datadump['no_portal']:
    551         dhcp_out['bridge0'].append("""\
    552    host fixed-%(ifname)s-%(fixed)s {
    553      hardware ethernet %(mac)s;
    554      fixed-address %(prefix)s.%(fixed)s;
    555    }
    556 """ % { 'ifname' : ifname, 'mac' : mac, 'prefix': dhcp_part, 'fixed' : fixed })
     557        dhcp_out[iface_key].append(textwrap.dedent("""\
     558            host fixed-%(ifname)s-%(fixed)s {
     559              hardware ethernet %(mac)s;
     560              fixed-address %(prefix)s.%(fixed)s;
     561            }
     562         """ % { 'ifname' : ifname, 'mac' : mac, 'prefix': dhcp_part, 'fixed' : fixed }))
    557563      fixed += 1
    558564
    559     dhcp_out['bridge0'].append("""\
    560    subnet %(autogen_subnet)s netmask %(autogen_netmask)s {
    561      range %(autogen_dhcp_start)s %(autogen_dhcp_stop)s;
    562      option routers %(autogen_addr)s;
    563      option domain-name-servers %(autogen_addr)s;
    564    }
    565 
    566 """ % datadump[iface_key])
     565    dhcp_out[iface_key].append(textwrap.dedent("""\
     566      subnet %(autogen_subnet)s netmask %(autogen_netmask)s {
     567        range %(autogen_dhcp_start)s %(autogen_dhcp_stop)s;
     568        option routers %(autogen_addr)s;
     569        option domain-name-servers %(autogen_addr)s;
     570      }
     571      """ % datadump[iface_key]))
    567572
    568573  for ifname,value in dhcp_out.iteritems():
    569     if ifname == 'bridge0':
    570       output += ("shared-network %s {\n" % ifname) + ''.join(value)  + '}\n\n'
    571     elif len(value) > 2:
     574    if len(value) > 2:
    572575      output += ("shared-network %s {\n" % ifname) + indent(''.join(value), 2)  + '\n}\n\n'
    573576    else:
     
    610613    datadump[iface_key]['autogen_dhcp_start'] = dhcp_part + "." + dhcp_start
    611614    datadump[iface_key]['autogen_dhcp_stop'] =  dhcp_part + "." + dhcp_stop
    612     output += "dhcp-range=%(autogen_ifname)s,%(autogen_dhcp_start)s,%(autogen_dhcp_stop)s,%(autogen_netmask)s,24h\n\n" % datadump[iface_key]
     615    output += "dhcp-range=%(autogen_iface)s,%(autogen_dhcp_start)s,%(autogen_dhcp_stop)s,%(autogen_netmask)s,24h\n\n" % datadump[iface_key]
    613616
    614617  return output
     
    633636  addrs_list = { 'lo0' : [("127.0.0.1/8", "LocalHost"), ("172.31.255.1/32","Proxy IP")] }
    634637  vlan_list = defaultdict(list)
     638  bridge_list = defaultdict(list)
    635639  flags_if = AutoVivification()
    636640  dhclient_if = {'lo0' : False}
     
    641645  masterip_used = False
    642646  for iface_key in get_interface_keys(datadump):
    643     if datadump[iface_key]['ip'].startswith(datadump['masterip']):
     647    if datadump[iface_key].has_key('ip') and datadump[iface_key]['ip'].startswith(datadump['masterip']):
    644648      masterip_used = True
    645649      break
     
    655659      vlan_list[ifacedump['autogen_ifbase']].append(ifacedump['autogen_vlan'])
    656660
     661    # If defined as bridge interface
     662    if ifacedump['autogen_bridge_member']:
     663      bridge_list[ifacedump['parent']].append(ifacedump['autogen_iface'])
     664
    657665    # Flag dhclient is possible
    658666    if not dhclient_if.has_key(ifname) or dhclient_if[ifname] == False:
     
    663671        flags_if[ifname]['ether'] = ifacedump['ether']
    664672
    665     # DHCP interfaces are to be added to bridge0
    666     if ifname.replace('_','.') in datadump['autogen_dhcp_interfaces']:
    667       ifname_base = 'bridge0'
    668     else:
    669       ifname_base = ifname
    670 
    671673    # Add interface IP to list
    672     item = (ifacedump['ip'], ifacedump['comment'])
    673     if addrs_list.has_key(ifname_base):
    674       addrs_list[ifname_base].append(item)
    675     else:
    676       addrs_list[ifname_base] = [item]
     674    if ifacedump.has_key('ip'):
     675      item = (ifacedump['ip'], ifacedump['comment'])
     676      if addrs_list.has_key(ifname):
     677        addrs_list[ifname].append(item)
     678      else:
     679        addrs_list[ifname] = [item]
    677680
    678681    # Alias only needs IP assignment for now, this might change if we
     
    710713    elif ifacedump['type'] in ['ethernet', 'eth']:
    711714      # No special config needed besides IP
    712       if ifacedump['autogen_bridge']:
    713         output += "cloned_interfaces='%(autogen_ifname)s'\n" % ifacedump
    714         output += "ifconfig_%s='addm %s up'\n" % (ifacedump['autogen_ifname'], ' addm '.join(ifacedump['autogen_bridge_interfaces']))
    715         for member in ifacedump['autogen_bridge_interfaces']:
    716           output += "ifconfig_%s='up'\n" % member
    717         output += "\n"
     715      pass
     716    elif ifacedump['type'] in ['vlan']:
     717      # VLAN member has no special configuration
     718      pass
    718719    else:
    719720      assert False, "Unknown type " + ifacedump['type']
    720721
    721   store = (addrs_list, vlan_list, dhclient_if, flags_if, output)
     722  store = (addrs_list, vlan_list, bridge_list, dhclient_if, flags_if, output)
    722723  interface_list_cache[datadump['autogen_item']] = store
    723724  return(store)
     
    807808  "
    808809
    809   captive_portal_interfaces="bridge0"
     810  captive_portal_interfaces="{{ autogen_dhcp_interfaces|join(',') }}"
    810811  externalif="{{ externalif|default('vr0', true) }}"
    811812  masterip="{{ masterip }}"
     
    874875    {% if autogen_dhcp_interfaces -%}
    875876    dhcpd_enable="YES"
    876     dhcpd_flags="$dhcpd_flags bridge0"
     877    dhcpd_flags="$dhcpd_flags {{ autogen_dhcp_interfaces|join(' ') }}"
    877878    {% endif -%}
    878879  {% elif board == "apu1d" %}
     
    884885    {% if autogen_dhcp_interfaces -%}
    885886    dhcpd_enable="YES"
    886     dhcpd_flags="$dhcpd_flags bridge0"
     887    dhcpd_flags="$dhcpd_flags {{ autogen_dhcp_interfaces|join(' ') }}"
    887888    {% endif -%}
    888889  {% endif -%}
     
    901902""")
    902903
    903   (addrs_list, vlan_list, dhclient_if, flags_if, extra_ouput) = make_interface_list(datadump)
     904  (addrs_list, vlan_list, bridge_list, dhclient_if, flags_if, extra_ouput) = make_interface_list(datadump)
    904905  for iface, vlans in vlan_list.items():
    905906    output += 'vlans_%s="%s"\n' % (iface, ' '.join(vlans))
     
    910911      output += "ifconfig_%s='up'\n" % iface
    911912
     913  output += "\n"
     914
     915  # Bridge configuration:
     916  if bridge_list.keys():
     917    output += "cloned_interfaces='%s'\n" % ' '.join(bridge_list.keys())
     918   
     919  for iface in bridge_list.keys():
     920    output += "create_args_%s='%s'\n" % (iface, ' '.join(['addm %(iface)s private %(iface)s' % {'iface': x} for x in bridge_list[iface]]))
     921
     922  # Bridge member interfaces not containing a configuration should be marked active explcitly.
     923  for _,members in bridge_list.items():
     924    for iface in members:
     925      if not iface in addrs_list.keys():
     926        output += "ifconfig_%s='up'\n" % iface
     927 
    912928  output += "\n"
    913929
     
    936952
    937953    idx_offset = 0
    938     if iface == 'bridge0':
    939       output += "cloned_interfaces='bridge0'\n"
    940       output += "create_args_bridge0='%s'\n" % ' '.join(['addm %s private %s' % (x, x) for x in datadump['autogen_dhcp_interfaces']])
    941       output += "ifconfig_bridge0='%s up'\n" % addrs[0][0]
    942     else:
    943       if flags_if[iface].has_key('ether'):
    944         output += "ifconfig_%s='link %s'\n" % (iface, flags_if[iface]['ether'])
    945         output += "ifconfig_%s_alias0='inet %s'\n" % (iface, addrs[0][0])
    946         idx_offset += 1
    947       else:   
    948         output += "ifconfig_%s='inet %s'\n" % (iface, addrs[0][0])
     954    # Set MAC is required
     955    if flags_if[iface].has_key('ether'):
     956      output += "ifconfig_%s='link %s'\n" % (iface, flags_if[iface]['ether'])
     957      output += "ifconfig_%s_alias0='inet %s'\n" % (iface, addrs[0][0])
     958      idx_offset += 1
     959    else:   
     960      output += "ifconfig_%s='inet %s'\n" % (iface, addrs[0][0])
    949961       
    950962    for idx, addr in enumerate(addrs[1:]):
    951963      output += "ifconfig_%s_alias%s='inet %s'\n" % (iface, idx + idx_offset, addr[0])
    952     if iface == 'bridge0':
    953       for dhcp_iface in datadump['autogen_dhcp_interfaces']:
    954         output += "ifconfig_%s='up'\n" % dhcp_iface.replace('.','_')
     964
    955965    output += "\n"
    956966
     
    10081018
    10091019def get_neighbours(datadump):
    1010   (addrs_list, _, dhclient_if, _, extra_ouput) = make_interface_list(datadump)
     1020  (addrs_list, _, _, dhclient_if, _, extra_ouput) = make_interface_list(datadump)
    10111021
    10121022  (poel, errors) = make_relations()
     
    10221032      for neighbour in poel[network(addr)]:
    10231033        if neighbour[0] != datadump['autogen_item']:
    1024           table.append((iface, neighbour[1]['ip'].split('/')[0], neighbour[0] + " (" + neighbour[1]['autogen_ifname'] + ")", neighbour[1]['comment']))
     1034          table.append((iface, neighbour[1]['ip'].split('/')[0], neighbour[0] + " (" + neighbour[1]['autogen_iface'] + ")", neighbour[1]['comment']))
    10251035  return table
    10261036
     
    10291039  table = []
    10301040  for iface_key in get_interface_keys(datadump, True):
    1031     # Quick to avoid listing ath(4) interface as attached device
    1032     if 'ath0' in iface_key:
     1041    ifacedump = datadump[iface_key]
     1042
     1043    if not ifacedump.has_key('ns_ip'):
    10331044      continue
    1034     ifacedump = datadump[iface_key]
    1035     if ifacedump.has_key('ns_ip'):
    1036       x_ip = ifacedump['ns_ip'].split('/')[0]
    1037     else:
    1038       x_ip = ifacedump['ip'].split('/')[0]
     1045
     1046    x_ip = ifacedump['ns_ip'].split('/')[0]
    10391047
    10401048    if 'mode' in ifacedump:
     
    10481056      device_type = 'Unknown'
    10491057
    1050     table.append((ifacedump['autogen_ifname'], x_mode, 'http://%s' % x_ip if url else x_ip, device_type))
     1058    table.append((ifacedump['autogen_iface'], x_mode, 'http://%s' % x_ip if url else x_ip, device_type))
    10511059  return table
    10521060
     
    11701178        col_width = [max(len(x) for x in col) for col in zip(*table)]
    11711179        for row in table:
    1172           lines += " - " + " || ".join("{:{}}".format(x, col_width[i]) for i, x in enumerate(row)) + "\n"
     1180          # replace('_','.') is a hack to convert vlan interfaces to proper named interfaces
     1181          lines += " - " + " || ".join("{:{}}".format(x.replace('_','.'), col_width[i]) for i, x in enumerate(row)) + "\n"
    11731182        return lines
    11741183
    1175   (addrs_list, vlan_list, dhclient_if, flags_if, extra_ouput) = make_interface_list(datadump)
     1184  (addrs_list, vlan_list, bridge_list, dhclient_if, flags_if, extra_ouput) = make_interface_list(datadump)
    11761185  table = []
    11771186  for iface,addrs in sorted(addrs_list.iteritems()):
     
    12251234  key_order = (
    12261235    ('comment', True),
    1227     ('ip', True),
     1236    ('parent', False),
     1237    ('ip', False),
    12281238    ('ether', False),
    12291239    ('desc', True),
     
    12451255    ('ns_type', False),
    12461256    ('bridge_type', False),
    1247     ('members', True),
    12481257    ('status', True),
    12491258  )
     
    18021811        ip2host[datadump['masterip']] = datadump['autogen_fqdn']
    18031812        for iface in get_interface_keys(datadump):
    1804           ip2host[datadump[iface]['autogen_gateway']] = datadump['autogen_fqdn']
     1813          if datadump[iface].has_key('autogen_gateway'):
     1814            ip2host[datadump[iface]['autogen_gateway']] = datadump['autogen_fqdn']
    18051815
    18061816      # Find dependency tree based on output of lvrouted.mytree of nearest node
Note: See TracChangeset for help on using the changeset viewer.