Index: tools/gformat.py
===================================================================
--- tools/gformat.py	(revision 13617)
+++ tools/gformat.py	(revision 13618)
@@ -216,7 +216,13 @@
         datadump[key]['autogen_vlan'] = False
 
-        datadump[key]['autogen_gateway'] = datadump[key]['ip'].split('/')[0]
+        datadump[key]['autogen_bridge_member'] = datadump[key].has_key('parent')
+        datadump[key]['autogen_bridge'] = datadump[key]['autogen_ifbase'].startswith('bridge')
+
+        if datadump[key].has_key('ip'):
+          datadump[key]['autogen_gateway'] = datadump[key]['ip'].split('/')[0]
+
         if datadump[key]['type'] in ['11a', '11b', '11g', 'wireless']:
           datadump[key]['autogen_ifname'] = 'wlan%i' % wlan_count
+          datadump[key]['autogen_iface'] = 'wlan%i' % wlan_count
           wlan_count += 1
         else:
@@ -224,8 +230,8 @@
           if len(key.split('_')) > 2 and key.split('_')[2].isdigit():
             datadump[key]['autogen_vlan'] = key.split('_')[2]
-
-        datadump[key]['autogen_bridge'] = datadump[key]['autogen_ifbase'].startswith('bridge')
-        if datadump[key]['autogen_bridge'] and not 'alias' in key:
-          datadump[key]['autogen_bridge_interfaces'] = datadump[key]['members'].split()
+            datadump[key]['autogen_iface'] = '.'.join(key.split('_')[1:])
+          else:
+            datadump[key]['autogen_iface'] = '_'.join(key.split('_')[1:])
+
     except Exception:
       print "# Error while processing interface %s" % key
@@ -522,8 +528,8 @@
       datadump[iface_key]['comment'] = None
 
-    if dhcp_type(datadump[iface_key]) != DHCP_SERVER:
-      dhcp_out[ifname].append("## %(autogen_ifname)s - %(comment)s\n" % datadump[iface_key])
-    else:
-      dhcp_out['bridge0'].append("   ## %(autogen_ifname)s - %(comment)s\n" % datadump[iface_key])
+    if not datadump[iface_key].has_key('ip'):
+      continue
+
+    dhcp_out[iface_key].append("## %(autogen_iface)s - %(comment)s\n" % datadump[iface_key])
 
     (addr, mask) = datadump[iface_key]['ip'].split('/')
@@ -533,5 +539,5 @@
 
     if dhcp_type(datadump[iface_key]) != DHCP_SERVER:
-      dhcp_out[ifname].append(textwrap.dedent("""\
+      dhcp_out[iface_key].append(textwrap.dedent("""\
         subnet %(autogen_subnet)s netmask %(autogen_netmask)s {
           ### not autoritive
@@ -549,25 +555,22 @@
       fixed = 5
       for mac in datadump['no_portal']:
-        dhcp_out['bridge0'].append("""\
-   host fixed-%(ifname)s-%(fixed)s {
-     hardware ethernet %(mac)s;
-     fixed-address %(prefix)s.%(fixed)s;
-   }
-""" % { 'ifname' : ifname, 'mac' : mac, 'prefix': dhcp_part, 'fixed' : fixed })
+        dhcp_out[iface_key].append(textwrap.dedent("""\
+            host fixed-%(ifname)s-%(fixed)s {
+              hardware ethernet %(mac)s;
+              fixed-address %(prefix)s.%(fixed)s;
+            }
+         """ % { 'ifname' : ifname, 'mac' : mac, 'prefix': dhcp_part, 'fixed' : fixed }))
       fixed += 1
 
-    dhcp_out['bridge0'].append("""\
-   subnet %(autogen_subnet)s netmask %(autogen_netmask)s {
-     range %(autogen_dhcp_start)s %(autogen_dhcp_stop)s;
-     option routers %(autogen_addr)s;
-     option domain-name-servers %(autogen_addr)s;
-   }
-
-""" % datadump[iface_key])
+    dhcp_out[iface_key].append(textwrap.dedent("""\
+      subnet %(autogen_subnet)s netmask %(autogen_netmask)s {
+        range %(autogen_dhcp_start)s %(autogen_dhcp_stop)s;
+        option routers %(autogen_addr)s;
+        option domain-name-servers %(autogen_addr)s;
+      }
+      """ % datadump[iface_key]))
 
   for ifname,value in dhcp_out.iteritems():
-    if ifname == 'bridge0':
-      output += ("shared-network %s {\n" % ifname) + ''.join(value)  + '}\n\n'
-    elif len(value) > 2:
+    if len(value) > 2:
       output += ("shared-network %s {\n" % ifname) + indent(''.join(value), 2)  + '\n}\n\n'
     else:
@@ -610,5 +613,5 @@
     datadump[iface_key]['autogen_dhcp_start'] = dhcp_part + "." + dhcp_start
     datadump[iface_key]['autogen_dhcp_stop'] =  dhcp_part + "." + dhcp_stop
-    output += "dhcp-range=%(autogen_ifname)s,%(autogen_dhcp_start)s,%(autogen_dhcp_stop)s,%(autogen_netmask)s,24h\n\n" % datadump[iface_key]
+    output += "dhcp-range=%(autogen_iface)s,%(autogen_dhcp_start)s,%(autogen_dhcp_stop)s,%(autogen_netmask)s,24h\n\n" % datadump[iface_key]
 
   return output
@@ -633,4 +636,5 @@
   addrs_list = { 'lo0' : [("127.0.0.1/8", "LocalHost"), ("172.31.255.1/32","Proxy IP")] }
   vlan_list = defaultdict(list)
+  bridge_list = defaultdict(list)
   flags_if = AutoVivification()
   dhclient_if = {'lo0' : False}
@@ -641,5 +645,5 @@
   masterip_used = False
   for iface_key in get_interface_keys(datadump):
-    if datadump[iface_key]['ip'].startswith(datadump['masterip']):
+    if datadump[iface_key].has_key('ip') and datadump[iface_key]['ip'].startswith(datadump['masterip']):
       masterip_used = True
       break
@@ -655,4 +659,8 @@
       vlan_list[ifacedump['autogen_ifbase']].append(ifacedump['autogen_vlan'])
 
+    # If defined as bridge interface
+    if ifacedump['autogen_bridge_member']:
+      bridge_list[ifacedump['parent']].append(ifacedump['autogen_iface'])
+
     # Flag dhclient is possible
     if not dhclient_if.has_key(ifname) or dhclient_if[ifname] == False:
@@ -663,16 +671,11 @@
         flags_if[ifname]['ether'] = ifacedump['ether']
 
-    # DHCP interfaces are to be added to bridge0
-    if ifname.replace('_','.') in datadump['autogen_dhcp_interfaces']:
-      ifname_base = 'bridge0'
-    else:
-      ifname_base = ifname
-
     # Add interface IP to list
-    item = (ifacedump['ip'], ifacedump['comment'])
-    if addrs_list.has_key(ifname_base):
-      addrs_list[ifname_base].append(item)
-    else:
-      addrs_list[ifname_base] = [item]
+    if ifacedump.has_key('ip'):
+      item = (ifacedump['ip'], ifacedump['comment'])
+      if addrs_list.has_key(ifname):
+        addrs_list[ifname].append(item)
+      else:
+        addrs_list[ifname] = [item]
 
     # Alias only needs IP assignment for now, this might change if we
@@ -710,14 +713,12 @@
     elif ifacedump['type'] in ['ethernet', 'eth']:
       # No special config needed besides IP
-      if ifacedump['autogen_bridge']:
-        output += "cloned_interfaces='%(autogen_ifname)s'\n" % ifacedump
-        output += "ifconfig_%s='addm %s up'\n" % (ifacedump['autogen_ifname'], ' addm '.join(ifacedump['autogen_bridge_interfaces']))
-        for member in ifacedump['autogen_bridge_interfaces']:
-          output += "ifconfig_%s='up'\n" % member
-        output += "\n"
+      pass
+    elif ifacedump['type'] in ['vlan']:
+      # VLAN member has no special configuration
+      pass
     else:
       assert False, "Unknown type " + ifacedump['type']
 
-  store = (addrs_list, vlan_list, dhclient_if, flags_if, output)
+  store = (addrs_list, vlan_list, bridge_list, dhclient_if, flags_if, output)
   interface_list_cache[datadump['autogen_item']] = store
   return(store)
@@ -807,5 +808,5 @@
   "
 
-  captive_portal_interfaces="bridge0"
+  captive_portal_interfaces="{{ autogen_dhcp_interfaces|join(',') }}"
   externalif="{{ externalif|default('vr0', true) }}"
   masterip="{{ masterip }}"
@@ -874,5 +875,5 @@
     {% if autogen_dhcp_interfaces -%}
     dhcpd_enable="YES"
-    dhcpd_flags="$dhcpd_flags bridge0"
+    dhcpd_flags="$dhcpd_flags {{ autogen_dhcp_interfaces|join(' ') }}"
     {% endif -%}
   {% elif board == "apu1d" %}
@@ -884,5 +885,5 @@
     {% if autogen_dhcp_interfaces -%}
     dhcpd_enable="YES"
-    dhcpd_flags="$dhcpd_flags bridge0"
+    dhcpd_flags="$dhcpd_flags {{ autogen_dhcp_interfaces|join(' ') }}"
     {% endif -%}
   {% endif -%}
@@ -901,5 +902,5 @@
 """)
 
-  (addrs_list, vlan_list, dhclient_if, flags_if, extra_ouput) = make_interface_list(datadump)
+  (addrs_list, vlan_list, bridge_list, dhclient_if, flags_if, extra_ouput) = make_interface_list(datadump)
   for iface, vlans in vlan_list.items():
     output += 'vlans_%s="%s"\n' % (iface, ' '.join(vlans))
@@ -910,4 +911,19 @@
       output += "ifconfig_%s='up'\n" % iface
 
+  output += "\n"
+
+  # Bridge configuration:
+  if bridge_list.keys():
+    output += "cloned_interfaces='%s'\n" % ' '.join(bridge_list.keys())
+    
+  for iface in bridge_list.keys():
+    output += "create_args_%s='%s'\n" % (iface, ' '.join(['addm %(iface)s private %(iface)s' % {'iface': x} for x in bridge_list[iface]]))
+
+  # Bridge member interfaces not containing a configuration should be marked active explcitly.
+  for _,members in bridge_list.items():
+    for iface in members:
+      if not iface in addrs_list.keys():
+        output += "ifconfig_%s='up'\n" % iface
+  
   output += "\n"
 
@@ -936,21 +952,15 @@
 
     idx_offset = 0
-    if iface == 'bridge0':
-      output += "cloned_interfaces='bridge0'\n"
-      output += "create_args_bridge0='%s'\n" % ' '.join(['addm %s private %s' % (x, x) for x in datadump['autogen_dhcp_interfaces']])
-      output += "ifconfig_bridge0='%s up'\n" % addrs[0][0]
-    else:
-      if flags_if[iface].has_key('ether'):
-        output += "ifconfig_%s='link %s'\n" % (iface, flags_if[iface]['ether'])
-        output += "ifconfig_%s_alias0='inet %s'\n" % (iface, addrs[0][0])
-        idx_offset += 1
-      else:   
-        output += "ifconfig_%s='inet %s'\n" % (iface, addrs[0][0])
+    # Set MAC is required
+    if flags_if[iface].has_key('ether'):
+      output += "ifconfig_%s='link %s'\n" % (iface, flags_if[iface]['ether'])
+      output += "ifconfig_%s_alias0='inet %s'\n" % (iface, addrs[0][0])
+      idx_offset += 1
+    else:   
+      output += "ifconfig_%s='inet %s'\n" % (iface, addrs[0][0])
         
     for idx, addr in enumerate(addrs[1:]):
       output += "ifconfig_%s_alias%s='inet %s'\n" % (iface, idx + idx_offset, addr[0]) 
-    if iface == 'bridge0':
-      for dhcp_iface in datadump['autogen_dhcp_interfaces']:
-        output += "ifconfig_%s='up'\n" % dhcp_iface.replace('.','_')
+
     output += "\n"
 
@@ -1008,5 +1018,5 @@
 
 def get_neighbours(datadump):
-  (addrs_list, _, dhclient_if, _, extra_ouput) = make_interface_list(datadump)
+  (addrs_list, _, _, dhclient_if, _, extra_ouput) = make_interface_list(datadump)
 
   (poel, errors) = make_relations()
@@ -1022,5 +1032,5 @@
       for neighbour in poel[network(addr)]:
         if neighbour[0] != datadump['autogen_item']:
-          table.append((iface, neighbour[1]['ip'].split('/')[0], neighbour[0] + " (" + neighbour[1]['autogen_ifname'] + ")", neighbour[1]['comment']))
+          table.append((iface, neighbour[1]['ip'].split('/')[0], neighbour[0] + " (" + neighbour[1]['autogen_iface'] + ")", neighbour[1]['comment']))
   return table
 
@@ -1029,12 +1039,10 @@
   table = []
   for iface_key in get_interface_keys(datadump, True):
-    # Quick to avoid listing ath(4) interface as attached device
-    if 'ath0' in iface_key:
+    ifacedump = datadump[iface_key]
+
+    if not ifacedump.has_key('ns_ip'):
       continue
-    ifacedump = datadump[iface_key]
-    if ifacedump.has_key('ns_ip'):
-      x_ip = ifacedump['ns_ip'].split('/')[0]
-    else:
-      x_ip = ifacedump['ip'].split('/')[0]
+
+    x_ip = ifacedump['ns_ip'].split('/')[0]
 
     if 'mode' in ifacedump:
@@ -1048,5 +1056,5 @@
       device_type = 'Unknown'
 
-    table.append((ifacedump['autogen_ifname'], x_mode, 'http://%s' % x_ip if url else x_ip, device_type))
+    table.append((ifacedump['autogen_iface'], x_mode, 'http://%s' % x_ip if url else x_ip, device_type))
   return table
 
@@ -1170,8 +1178,9 @@
         col_width = [max(len(x) for x in col) for col in zip(*table)]
         for row in table:
-          lines += " - " + " || ".join("{:{}}".format(x, col_width[i]) for i, x in enumerate(row)) + "\n"
+          # replace('_','.') is a hack to convert vlan interfaces to proper named interfaces
+          lines += " - " + " || ".join("{:{}}".format(x.replace('_','.'), col_width[i]) for i, x in enumerate(row)) + "\n"
         return lines
 
-  (addrs_list, vlan_list, dhclient_if, flags_if, extra_ouput) = make_interface_list(datadump)
+  (addrs_list, vlan_list, bridge_list, dhclient_if, flags_if, extra_ouput) = make_interface_list(datadump)
   table = []
   for iface,addrs in sorted(addrs_list.iteritems()):
@@ -1225,5 +1234,6 @@
   key_order = (
     ('comment', True),
-    ('ip', True),
+    ('parent', False),
+    ('ip', False),
     ('ether', False),
     ('desc', True),
@@ -1245,5 +1255,4 @@
     ('ns_type', False),
     ('bridge_type', False),
-    ('members', True),
     ('status', True),
   )
@@ -1802,5 +1811,6 @@
         ip2host[datadump['masterip']] = datadump['autogen_fqdn']
         for iface in get_interface_keys(datadump):
-          ip2host[datadump[iface]['autogen_gateway']] = datadump['autogen_fqdn']
+          if datadump[iface].has_key('autogen_gateway'):
+            ip2host[datadump[iface]['autogen_gateway']] = datadump['autogen_fqdn']
 
       # Find dependency tree based on output of lvrouted.mytree of nearest node
