Index: sys/netgraph/ng_bridge.c
===================================================================
--- sys/netgraph/ng_bridge.c    (revision 351934)
+++ sys/netgraph/ng_bridge.c    (working copy)
@@ -101,12 +101,13 @@
 /* Per-node private data */
 struct ng_bridge_private {
        struct ng_bridge_bucket *tab;           /* hash table bucket array */
-       struct ng_bridge_link   *links[NG_BRIDGE_MAX_LINKS];
+       struct ng_bridge_link   **links;
        struct ng_bridge_config conf;           /* node configuration */
        node_p                  node;           /* netgraph node */
        u_int                   numHosts;       /* num entries in table */
        u_int                   numBuckets;     /* num buckets in table */
        u_int                   hashMask;       /* numBuckets - 1 */
+       u_int                   maxLinks;       /* allocated links */
        int                     numLinks;       /* num connected links */
        int                     persistent;     /* can exist w/o hooks */
        struct callout          timer;          /* one second periodic timer */
@@ -133,6 +134,7 @@
 /* Other internal functions */
 static struct  ng_bridge_host *ng_bridge_get(priv_p priv, const u_char *addr);
 static int     ng_bridge_put(priv_p priv, const u_char *addr, int linkNum);
+static int     ng_bridge_morelinks(node_p node, int linkNum);
 static void    ng_bridge_rehash(priv_p priv);
 static void    ng_bridge_remove_hosts(priv_p priv, int linkNum);
 static void    ng_bridge_timeout(node_p node, hook_p hook, void *arg1, int arg2);
@@ -200,16 +202,8 @@
 };
 
 /* Parse type for struct ng_bridge_config */
-static const struct ng_parse_fixedarray_info ng_bridge_ipfwary_type_info = {
-       &ng_parse_uint8_type,
-       NG_BRIDGE_MAX_LINKS
-};
-static const struct ng_parse_type ng_bridge_ipfwary_type = {
-       &ng_parse_fixedarray_type,
-       &ng_bridge_ipfwary_type_info
-};
 static const struct ng_parse_struct_field ng_bridge_config_type_fields[]
-       = NG_BRIDGE_CONFIG_TYPE_INFO(&ng_bridge_ipfwary_type);
+       = NG_BRIDGE_CONFIG_TYPE_INFO;
 static const struct ng_parse_type ng_bridge_config_type = {
        &ng_parse_struct_type,
        &ng_bridge_config_type_fields
@@ -315,6 +309,9 @@
        ng_callout_init(&priv->timer);
 
        /* Allocate and initialize hash table, etc. */
+       priv->maxLinks = NG_BRIDGE_INC_LINKS;
+       priv->links = malloc(priv->maxLinks * sizeof(*priv->links),
+           M_NETGRAPH_BRIDGE, M_WAITOK | M_ZERO);
        priv->tab = malloc(MIN_BUCKETS * sizeof(*priv->tab),
            M_NETGRAPH_BRIDGE, M_WAITOK | M_ZERO);
        priv->numBuckets = MIN_BUCKETS;
@@ -357,13 +354,17 @@
                const char *cp;
                char *eptr;
                u_long linkNum;
+               int error;
 
                cp = name + strlen(NG_BRIDGE_HOOK_LINK_PREFIX);
                if (!isdigit(*cp) || (cp[0] == '0' && cp[1] != '\0'))
                        return (EINVAL);
                linkNum = strtoul(cp, &eptr, 10);
-               if (*eptr != '\0' || linkNum >= NG_BRIDGE_MAX_LINKS)
+               if (*eptr != '\0')
                        return (EINVAL);
+               if (linkNum >= priv->maxLinks)
+                 if ((error = ng_bridge_morelinks(node, linkNum)) != 0)
+                       return error;
                if (priv->links[linkNum] != NULL)
                        return (EISCONN);
                priv->links[linkNum] = malloc(sizeof(*priv->links[linkNum]),
@@ -412,7 +413,6 @@
                case NGM_BRIDGE_SET_CONFIG:
                    {
                        struct ng_bridge_config *conf;
-                       int i;
 
                        if (msg->header.arglen
                            != sizeof(struct ng_bridge_config)) {
@@ -421,8 +421,6 @@
                        }
                        conf = (struct ng_bridge_config *)msg->data;
                        priv->conf = *conf;
-                       for (i = 0; i < NG_BRIDGE_MAX_LINKS; i++)
-                               priv->conf.ipfw[i] = !!priv->conf.ipfw[i];
                        break;
                    }
                case NGM_BRIDGE_RESET:
@@ -433,7 +431,7 @@
                        ng_bridge_remove_hosts(priv, -1);
 
                        /* Reset all loop detection counters and stats */
-                       for (i = 0; i < NG_BRIDGE_MAX_LINKS; i++) {
+                       for (i = 0; i < priv->maxLinks; i++) {
                                if (priv->links[i] == NULL)
                                        continue;
                                priv->links[i]->loopCount = 0;
@@ -455,7 +453,7 @@
                                break;
                        }
                        linkNum = *((u_int32_t *)msg->data);
-                       if (linkNum < 0 || linkNum >= NG_BRIDGE_MAX_LINKS) {
+                       if (linkNum < 0 || linkNum >= priv->maxLinks) {
                                error = EINVAL;
                                break;
                        }
@@ -539,7 +537,7 @@
        NGI_GET_M(item, m);
        /* Get link number */
        linkNum = (intptr_t)NG_HOOK_PRIVATE(hook);
-       KASSERT(linkNum >= 0 && linkNum < NG_BRIDGE_MAX_LINKS,
+       KASSERT(linkNum >= 0 && linkNum < priv->maxLinks,
            ("%s: linkNum=%u", __func__, linkNum));
        link = priv->links[linkNum];
        KASSERT(link != NULL, ("%s: link%d null", __func__, linkNum));
@@ -779,6 +777,7 @@
        ng_uncallout(&priv->timer, node);
        NG_NODE_SET_PRIVATE(node, NULL);
        NG_NODE_UNREF(node);
+       free(priv->links, M_NETGRAPH_BRIDGE);
        free(priv->tab, M_NETGRAPH_BRIDGE);
        free(priv, M_NETGRAPH_BRIDGE);
        return (0);
@@ -795,7 +794,7 @@
 
        /* Get link number */
        linkNum = (intptr_t)NG_HOOK_PRIVATE(hook);
-       KASSERT(linkNum >= 0 && linkNum < NG_BRIDGE_MAX_LINKS,
+       KASSERT(linkNum >= 0 && linkNum < priv->maxLinks,
            ("%s: linkNum=%u", __func__, linkNum));
 
        /* Remove all hosts associated with this link */
@@ -944,6 +943,33 @@
 ******************************************************************/
 
 /*
+ * Expand table of links, if necessary
+ */
+static int
+ng_bridge_morelinks(node_p node, int linkNum)
+{
+       priv_p priv = NG_NODE_PRIVATE(node);
+       int newsize = priv->maxLinks + NG_BRIDGE_INC_LINKS;
+       void * newp;
+       
+       if (linkNum >= newsize || linkNum < 0)
+         return (EINVAL);
+
+       if (linkNum < priv->maxLinks)
+         return 0;
+       
+       newp = realloc(priv->links,
+                      newsize * sizeof(*priv->links),
+                      M_NETGRAPH_BRIDGE, M_WAITOK | M_ZERO);
+       if(newp == NULL)               /* old array intact */
+         return (ENOMEM);
+
+       priv->links = newp;
+       priv->maxLinks = newsize;
+       return 0;
+}
+
+/*
  * Remove all hosts associated with a specific link from the hashtable.
  * If linkNum == -1, then remove all hosts in the table.
  */
@@ -1015,7 +1041,7 @@
        ng_bridge_rehash(priv);
 
        /* Decrease loop counter on muted looped back links */
-       for (counter = linkNum = 0; linkNum < NG_BRIDGE_MAX_LINKS; linkNum++) {
+       for (counter = linkNum = 0; linkNum < priv->maxLinks; linkNum++) {
                struct ng_bridge_link *const link = priv->links[linkNum];
 
                if (link != NULL) {
Index: sys/netgraph/ng_bridge.h
===================================================================
--- sys/netgraph/ng_bridge.h    (revision 351934)
+++ sys/netgraph/ng_bridge.h    (working copy)
@@ -45,18 +45,17 @@
 
 /* Node type name and magic cookie */
 #define NG_BRIDGE_NODE_TYPE            "bridge"
-#define NGM_BRIDGE_COOKIE              967239368
+#define NGM_BRIDGE_COOKIE              1569321993
 
 /* Hook names */
 #define NG_BRIDGE_HOOK_LINK_PREFIX     "link"   /* append decimal integer */
 #define NG_BRIDGE_HOOK_LINK_FMT                "link%d" /* for use with printf(3) */
 
-/* Maximum number of supported links */
-#define NG_BRIDGE_MAX_LINKS            32
+/* Increment for number of supported links */
+#define NG_BRIDGE_INC_LINKS            32
 
 /* Node configuration structure */
 struct ng_bridge_config {
-       u_char          ipfw[NG_BRIDGE_MAX_LINKS];      /* enable ipfw */
        u_char          debugLevel;             /* debug level */
        u_int32_t       loopTimeout;            /* link loopback mute time */
        u_int32_t       maxStaleness;           /* max host age before nuking */
@@ -64,8 +63,7 @@
 };
 
 /* Keep this in sync with the above structure definition */
-#define NG_BRIDGE_CONFIG_TYPE_INFO(ainfo)      {               \
-         { "ipfw",             (ainfo)                 },      \
+#define NG_BRIDGE_CONFIG_TYPE_INFO     {                       \
          { "debugLevel",       &ng_parse_uint8_type    },      \
          { "loopTimeout",      &ng_parse_uint32_type   },      \
          { "maxStaleness",     &ng_parse_uint32_type   },      \
Index: share/man/man4/ng_bridge.4
===================================================================
--- share/man/man4/ng_bridge.4  (revision 351934)
+++ share/man/man4/ng_bridge.4  (working copy)
@@ -76,14 +76,12 @@
 .Xr ipfirewall 4
 mechanism on a per-link basis is not yet implemented.
 .Sh HOOKS
-This node type supports up to
-.Dv NG_BRIDGE_MAX_LINKS
-hooks.
+This node type supports an unlimited number of hooks.
 Each connected hook represents a bridged link.
 The hooks are named
 .Dv link0 ,
 .Dv link1 ,
-etc.
+etc. and are allocated sequentially.
 Typically these hooks are connected to the
 .Dv lower
 hooks of one or more
@@ -106,7 +104,6 @@
 .Bd -literal -offset 0n
 /* Node configuration structure */
 struct ng_bridge_config {
-  u_char      ipfw[NG_BRIDGE_MAX_LINKS]; /* enable ipfw */
   u_char      debugLevel;           /* debug level */
   uint32_t    loopTimeout;          /* link loopback mute time */
   uint32_t    maxStaleness;         /* max host age before nuking */
@@ -115,11 +112,6 @@
 .Ed
 .Pp
 The
-.Dv ipfw
-array enables
-.Xr ipfirewall 4
-processing of IP packets received on the corresponding links.
-The
 .Dv debugLevel
 field sets the debug level on the node.
 At level of 2 or greater, detected loops are logged.