Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153384626
D44615.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D44615.diff
View Options
diff --git a/share/man/man4/ng_bridge.4 b/share/man/man4/ng_bridge.4
--- a/share/man/man4/ng_bridge.4
+++ b/share/man/man4/ng_bridge.4
@@ -32,7 +32,7 @@
.\"
.\" Author: Archie Cobbs <archie@FreeBSD.org>
.\"
-.Dd May 13, 2021
+.Dd April 8, 2024
.Dt NG_BRIDGE 4
.Os
.Sh NAME
@@ -108,6 +108,17 @@
.Ar uplink
hooks, so no functionality is lost.
.Pp
+The
+.Ar linkX
+and
+.Ar uplinkX
+hook numbers can be autoassigned.
+If a new hook name was specified as
+.Ar link
+or
+.Ar uplink
+the node will append lowest available valid number to the name of the new hook.
+.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
--- a/sys/netgraph/ng_bridge.c
+++ b/sys/netgraph/ng_bridge.c
@@ -124,6 +124,8 @@
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 @@
/* 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_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_NODE_SET_PRIVATE(node, priv);
priv->node = node;
+ /* Allocators for links. Historically "uplink0" is not allowed. */
+ priv->linkUnit = new_unrhdr(0, INT_MAX, NULL);
+ priv->uplinkUnit = new_unrhdr(1, INT_MAX, NULL);
+
/* 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,50 @@
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];
+ int rvnum __diagused;
+
+ linkNum = strtoul(name + pfx->len, NULL, 10);
+ /* Validate 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);
+ rvnum = alloc_unr_specific(unit, linkNum);
+ MPASS(rvnum == linkNum);
+ } else {
+ /* auto-assign and update hook name */
+ linkNum = alloc_unr(unit);
+ MPASS(linkNum != -1);
+ 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 +467,7 @@
return (0);
nomem:
+ free_unr(unit, linkNum);
ng_bridge_free_link(link);
return (ENOMEM);
}
@@ -914,6 +951,8 @@
("%s: numLinks=%d numHosts=%d",
__func__, priv->numLinks, priv->numHosts));
ng_uncallout(&priv->timer, node);
+ delete_unrhdr(priv->linkUnit);
+ delete_unrhdr(priv->uplinkUnit);
NG_NODE_SET_PRIVATE(node, NULL);
NG_NODE_UNREF(node);
free(priv->tab, M_NETGRAPH_BRIDGE);
@@ -927,8 +966,11 @@
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 +979,9 @@
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 +1140,19 @@
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.
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Apr 21, 8:34 PM (12 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31932066
Default Alt Text
D44615.diff (6 KB)
Attached To
Mode
D44615: Allow ng_bridge to automatically assign [up]link numbers for connect messages.
Attached
Detach File
Event Timeline
Log In to Comment