FreeBSD Bugzilla – Attachment 249705 Details for
Bug 278130
[netgraph][patch] ng_bridge hooks should auto assign number for [up]link
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
updated patch for CURRENT
CURRENT-ng_bridge.patch (text/plain), 6.91 KB, created by
David Marker
on 2024-04-04 14:25:55 UTC
(
hide
)
Description:
updated patch for CURRENT
Filename:
MIME Type:
Creator:
David Marker
Created:
2024-04-04 14:25:55 UTC
Size:
6.91 KB
patch
obsolete
>From fb8c6c4544ab3c6ef1b686638d3b5a272991f5fd Mon Sep 17 00:00:00 2001 >From: David Marker <dave@freedave.net> >Date: Thu, 4 Apr 2024 08:15:44 -0300 >Subject: [PATCH] ng_bridge hooks auto assign number > >--- > share/man/man4/ng_bridge.4 | 7 +++ > sys/netgraph/ng_bridge.c | 99 +++++++++++++++++++++++++++++--------- > 2 files changed, 83 insertions(+), 23 deletions(-) > >diff --git a/share/man/man4/ng_bridge.4 b/share/man/man4/ng_bridge.4 >index 45bc6b3cb..585674f0a 100644 >--- a/share/man/man4/ng_bridge.4 >+++ b/share/man/man4/ng_bridge.4 >@@ -108,6 +108,13 @@ Frames with unknown MACs are always sent out to > .Ar uplink > hooks, so no functionality is lost. > .Pp >+To have the bridge assign an [up]link number for you, simply name your >+hook >+.Ar link >+or >+.Ar uplink >+and omit giving it a number. >+.Pp > Frames with unknown destination MAC addresses are replicated to any > available hook, unless the first connected hook is an > .Ar uplink >diff --git a/sys/netgraph/ng_bridge.c b/sys/netgraph/ng_bridge.c >index ebe811acc..363c8d3d3 100644 >--- a/sys/netgraph/ng_bridge.c >+++ b/sys/netgraph/ng_bridge.c >@@ -124,6 +124,8 @@ struct ng_bridge_private { > unsigned int persistent : 1, /* can exist w/o hooks */ > sendUnknown : 1;/* links receive unknowns by default */ > struct callout timer; /* one second periodic timer */ >+ struct unrhdr *linkUnit; /* link unit number allocator */ >+ struct unrhdr *uplinkUnit; /* uplink unit number allocator */ > }; > typedef struct ng_bridge_private *priv_p; > typedef struct ng_bridge_private const *priv_cp; /* read only access */ >@@ -140,6 +142,21 @@ struct ng_bridge_host { > /* Hash table bucket declaration */ > SLIST_HEAD(ng_bridge_bucket, ng_bridge_host); > >+/* [up]link prefix matching */ >+struct ng_link_prefix { >+ const char * const prefix; >+ size_t len; >+}; >+ >+static const struct ng_link_prefix link_pfx = { >+ .prefix = NG_BRIDGE_HOOK_LINK_PREFIX, >+ .len = sizeof(NG_BRIDGE_HOOK_LINK_PREFIX) - 1, >+}; >+static const struct ng_link_prefix uplink_pfx = { >+ .prefix = NG_BRIDGE_HOOK_UPLINK_PREFIX, >+ .len = sizeof(NG_BRIDGE_HOOK_UPLINK_PREFIX) - 1, >+}; >+ > /* Netgraph node methods */ > static ng_constructor_t ng_bridge_constructor; > static ng_rcvmsg_t ng_bridge_rcvmsg; >@@ -149,6 +166,7 @@ static ng_rcvdata_t ng_bridge_rcvdata; > static ng_disconnect_t ng_bridge_disconnect; > > /* Other internal functions */ >+static const struct ng_link_prefix *ng_get_link_prefix(const char *name); > static void ng_bridge_free_link(link_p link); > static struct ng_bridge_host *ng_bridge_get(priv_cp priv, const u_char *addr); > static int ng_bridge_put(priv_p priv, const u_char *addr, link_p link); >@@ -350,6 +368,10 @@ ng_bridge_constructor(node_p node) > NG_NODE_SET_PRIVATE(node, priv); > priv->node = node; > >+ /* allocator for links */ >+ priv->linkUnit = new_unrhdr(0, INT_MAX, NULL); >+ priv->uplinkUnit = new_unrhdr(1, INT_MAX, NULL); /* 0 not valid uplink */ >+ > /* Start timer; timer is always running while node is alive */ > ng_callout(&priv->timer, node, NULL, hz, ng_bridge_timeout, NULL, 0); > >@@ -364,36 +386,46 @@ static int > ng_bridge_newhook(node_p node, hook_p hook, const char *name) > { > const priv_p priv = NG_NODE_PRIVATE(node); >- char linkName[NG_HOOKSIZ]; >- u_int32_t linkNum; > link_p link; >- const char *prefix = NG_BRIDGE_HOOK_LINK_PREFIX; > bool isUplink; >+ uint32_t linkNum; >+ struct unrhdr *unit; >+ >+ const struct ng_link_prefix *pfx = ng_get_link_prefix(name); >+ if (pfx == NULL) >+ return (EINVAL); /* not a valid prefix */ >+ >+ isUplink = (pfx == &uplink_pfx); >+ unit = isUplink ? priv->uplinkUnit : priv->linkUnit; >+ >+ if (strlen(name) > pfx->len) { /* given number */ >+ char linkName[NG_HOOKSIZ]; >+ /* primitive parsing */ >+ linkNum = strtoul(name + pfx->len, NULL, 10); >+ /* validation by comparing against the reconstucted name */ >+ snprintf(linkName, sizeof(linkName), "%s%u", pfx->prefix, >+ linkNum); >+ if (strcmp(linkName, name) != 0) >+ return (EINVAL); >+ if (linkNum == 0 && isUplink) >+ return (EINVAL); >+ alloc_unr_specific(unit, linkNum); >+ } else { >+ /* auto-assign and update hook name */ >+ linkNum = alloc_unr(unit); >+ snprintf(NG_HOOK_NAME(hook), NG_HOOKSIZ, "%s%u", pfx->prefix, linkNum); >+ } > >- /* Check for a link hook */ >- if (strlen(name) <= strlen(prefix)) >- return (EINVAL); /* Unknown hook name */ >- >- isUplink = (name[0] == 'u'); >- if (isUplink) >- prefix = NG_BRIDGE_HOOK_UPLINK_PREFIX; >- >- /* primitive parsing */ >- linkNum = strtoul(name + strlen(prefix), NULL, 10); >- /* validation by comparing against the reconstucted name */ >- snprintf(linkName, sizeof(linkName), "%s%u", prefix, linkNum); >- if (strcmp(linkName, name) != 0) >- return (EINVAL); >- >- if (linkNum == 0 && isUplink) >- return (EINVAL); >- >- if(NG_PEER_NODE(hook) == node) >+ if(NG_PEER_NODE(hook) == node) { >+ free_unr(unit, linkNum); > return (ELOOP); >+ } > > link = malloc(sizeof(*link), M_NETGRAPH_BRIDGE, M_NOWAIT | M_ZERO); >- if (link == NULL) >+ if (link == NULL) { >+ free_unr(unit, linkNum); > return (ENOMEM); >+ } > > #define NG_BRIDGE_COUNTER_ALLOC(f) do { \ > link->stats.f = counter_u64_alloc(M_NOWAIT); \ >@@ -431,6 +463,7 @@ ng_bridge_newhook(node_p node, hook_p hook, const char *name) > return (0); > > nomem: >+ free_unr(unit, linkNum); > ng_bridge_free_link(link); > return (ENOMEM); > } >@@ -913,6 +946,8 @@ ng_bridge_shutdown(node_p node) > KASSERT(priv->numLinks == 0 && priv->numHosts == 0, > ("%s: numLinks=%d numHosts=%d", > __func__, priv->numLinks, priv->numHosts)); >+ delete_unrhdr(priv->linkUnit); /* assert means no need to clear */ >+ delete_unrhdr(priv->uplinkUnit); > ng_uncallout(&priv->timer, node); > NG_NODE_SET_PRIVATE(node, NULL); > NG_NODE_UNREF(node); >@@ -927,8 +962,11 @@ ng_bridge_shutdown(node_p node) > static int > ng_bridge_disconnect(hook_p hook) > { >+ char *name = NG_HOOK_NAME(hook); > const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); > link_p link = NG_HOOK_PRIVATE(hook); >+ const struct ng_link_prefix *pfx = ng_get_link_prefix(name); >+ uint32_t linkNum; > > /* Remove all hosts associated with this link */ > ng_bridge_remove_hosts(priv, link); >@@ -937,6 +975,9 @@ ng_bridge_disconnect(hook_p hook) > ng_bridge_free_link(link); > priv->numLinks--; > >+ linkNum = strtoul(name + pfx->len, NULL, 10); >+ free_unr(pfx == &link_pfx ? priv->linkUnit: priv->uplinkUnit, linkNum); >+ > /* If no more hooks, go away */ > if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) > && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook))) >@@ -1095,6 +1136,18 @@ ng_bridge_rehash(priv_p priv) > MISC FUNCTIONS > ******************************************************************/ > >+static const struct ng_link_prefix * >+ng_get_link_prefix(const char *name) >+{ >+ static const struct ng_link_prefix *pfxs[] = { &link_pfx, &uplink_pfx, }; >+ >+ for (u_int i = 0; i < nitems(pfxs); i++) >+ if (strncmp(pfxs[i]->prefix, name, pfxs[i]->len) == 0) >+ return (pfxs[i]); >+ >+ return (NULL); >+} >+ > /* > * Remove all hosts associated with a specific link from the hashtable. > * If linkNum == -1, then remove all hosts in the table. >-- >2.44.0 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 278130
:
249661
| 249705