Lines 101-112
Link Here
|
101 |
/* Per-node private data */ |
101 |
/* Per-node private data */ |
102 |
struct ng_bridge_private { |
102 |
struct ng_bridge_private { |
103 |
struct ng_bridge_bucket *tab; /* hash table bucket array */ |
103 |
struct ng_bridge_bucket *tab; /* hash table bucket array */ |
104 |
struct ng_bridge_link *links[NG_BRIDGE_MAX_LINKS]; |
104 |
struct ng_bridge_link **links; |
105 |
struct ng_bridge_config conf; /* node configuration */ |
105 |
struct ng_bridge_config conf; /* node configuration */ |
106 |
node_p node; /* netgraph node */ |
106 |
node_p node; /* netgraph node */ |
107 |
u_int numHosts; /* num entries in table */ |
107 |
u_int numHosts; /* num entries in table */ |
108 |
u_int numBuckets; /* num buckets in table */ |
108 |
u_int numBuckets; /* num buckets in table */ |
109 |
u_int hashMask; /* numBuckets - 1 */ |
109 |
u_int hashMask; /* numBuckets - 1 */ |
|
|
110 |
u_int maxLinks; /* allocated links */ |
110 |
int numLinks; /* num connected links */ |
111 |
int numLinks; /* num connected links */ |
111 |
int persistent; /* can exist w/o hooks */ |
112 |
int persistent; /* can exist w/o hooks */ |
112 |
struct callout timer; /* one second periodic timer */ |
113 |
struct callout timer; /* one second periodic timer */ |
Lines 133-138
Link Here
|
133 |
/* Other internal functions */ |
134 |
/* Other internal functions */ |
134 |
static struct ng_bridge_host *ng_bridge_get(priv_p priv, const u_char *addr); |
135 |
static struct ng_bridge_host *ng_bridge_get(priv_p priv, const u_char *addr); |
135 |
static int ng_bridge_put(priv_p priv, const u_char *addr, int linkNum); |
136 |
static int ng_bridge_put(priv_p priv, const u_char *addr, int linkNum); |
|
|
137 |
static int ng_bridge_morelinks(node_p node, int linkNum); |
136 |
static void ng_bridge_rehash(priv_p priv); |
138 |
static void ng_bridge_rehash(priv_p priv); |
137 |
static void ng_bridge_remove_hosts(priv_p priv, int linkNum); |
139 |
static void ng_bridge_remove_hosts(priv_p priv, int linkNum); |
138 |
static void ng_bridge_timeout(node_p node, hook_p hook, void *arg1, int arg2); |
140 |
static void ng_bridge_timeout(node_p node, hook_p hook, void *arg1, int arg2); |
Lines 200-215
Link Here
|
200 |
}; |
202 |
}; |
201 |
|
203 |
|
202 |
/* Parse type for struct ng_bridge_config */ |
204 |
/* Parse type for struct ng_bridge_config */ |
203 |
static const struct ng_parse_fixedarray_info ng_bridge_ipfwary_type_info = { |
|
|
204 |
&ng_parse_uint8_type, |
205 |
NG_BRIDGE_MAX_LINKS |
206 |
}; |
207 |
static const struct ng_parse_type ng_bridge_ipfwary_type = { |
208 |
&ng_parse_fixedarray_type, |
209 |
&ng_bridge_ipfwary_type_info |
210 |
}; |
211 |
static const struct ng_parse_struct_field ng_bridge_config_type_fields[] |
205 |
static const struct ng_parse_struct_field ng_bridge_config_type_fields[] |
212 |
= NG_BRIDGE_CONFIG_TYPE_INFO(&ng_bridge_ipfwary_type); |
206 |
= NG_BRIDGE_CONFIG_TYPE_INFO; |
213 |
static const struct ng_parse_type ng_bridge_config_type = { |
207 |
static const struct ng_parse_type ng_bridge_config_type = { |
214 |
&ng_parse_struct_type, |
208 |
&ng_parse_struct_type, |
215 |
&ng_bridge_config_type_fields |
209 |
&ng_bridge_config_type_fields |
Lines 315-320
Link Here
|
315 |
ng_callout_init(&priv->timer); |
309 |
ng_callout_init(&priv->timer); |
316 |
|
310 |
|
317 |
/* Allocate and initialize hash table, etc. */ |
311 |
/* Allocate and initialize hash table, etc. */ |
|
|
312 |
priv->maxLinks = NG_BRIDGE_INC_LINKS; |
313 |
priv->links = malloc(priv->maxLinks * sizeof(*priv->links), |
314 |
M_NETGRAPH_BRIDGE, M_WAITOK | M_ZERO); |
318 |
priv->tab = malloc(MIN_BUCKETS * sizeof(*priv->tab), |
315 |
priv->tab = malloc(MIN_BUCKETS * sizeof(*priv->tab), |
319 |
M_NETGRAPH_BRIDGE, M_WAITOK | M_ZERO); |
316 |
M_NETGRAPH_BRIDGE, M_WAITOK | M_ZERO); |
320 |
priv->numBuckets = MIN_BUCKETS; |
317 |
priv->numBuckets = MIN_BUCKETS; |
Lines 357-369
Link Here
|
357 |
const char *cp; |
354 |
const char *cp; |
358 |
char *eptr; |
355 |
char *eptr; |
359 |
u_long linkNum; |
356 |
u_long linkNum; |
|
|
357 |
int error; |
360 |
|
358 |
|
361 |
cp = name + strlen(NG_BRIDGE_HOOK_LINK_PREFIX); |
359 |
cp = name + strlen(NG_BRIDGE_HOOK_LINK_PREFIX); |
362 |
if (!isdigit(*cp) || (cp[0] == '0' && cp[1] != '\0')) |
360 |
if (!isdigit(*cp) || (cp[0] == '0' && cp[1] != '\0')) |
363 |
return (EINVAL); |
361 |
return (EINVAL); |
364 |
linkNum = strtoul(cp, &eptr, 10); |
362 |
linkNum = strtoul(cp, &eptr, 10); |
365 |
if (*eptr != '\0' || linkNum >= NG_BRIDGE_MAX_LINKS) |
363 |
if (*eptr != '\0') |
366 |
return (EINVAL); |
364 |
return (EINVAL); |
|
|
365 |
if (linkNum >= priv->maxLinks) |
366 |
if ((error = ng_bridge_morelinks(node, linkNum)) != 0) |
367 |
return error; |
367 |
if (priv->links[linkNum] != NULL) |
368 |
if (priv->links[linkNum] != NULL) |
368 |
return (EISCONN); |
369 |
return (EISCONN); |
369 |
priv->links[linkNum] = malloc(sizeof(*priv->links[linkNum]), |
370 |
priv->links[linkNum] = malloc(sizeof(*priv->links[linkNum]), |
Lines 412-418
Link Here
|
412 |
case NGM_BRIDGE_SET_CONFIG: |
413 |
case NGM_BRIDGE_SET_CONFIG: |
413 |
{ |
414 |
{ |
414 |
struct ng_bridge_config *conf; |
415 |
struct ng_bridge_config *conf; |
415 |
int i; |
|
|
416 |
|
416 |
|
417 |
if (msg->header.arglen |
417 |
if (msg->header.arglen |
418 |
!= sizeof(struct ng_bridge_config)) { |
418 |
!= sizeof(struct ng_bridge_config)) { |
Lines 421-428
Link Here
|
421 |
} |
421 |
} |
422 |
conf = (struct ng_bridge_config *)msg->data; |
422 |
conf = (struct ng_bridge_config *)msg->data; |
423 |
priv->conf = *conf; |
423 |
priv->conf = *conf; |
424 |
for (i = 0; i < NG_BRIDGE_MAX_LINKS; i++) |
|
|
425 |
priv->conf.ipfw[i] = !!priv->conf.ipfw[i]; |
426 |
break; |
424 |
break; |
427 |
} |
425 |
} |
428 |
case NGM_BRIDGE_RESET: |
426 |
case NGM_BRIDGE_RESET: |
Lines 433-439
Link Here
|
433 |
ng_bridge_remove_hosts(priv, -1); |
431 |
ng_bridge_remove_hosts(priv, -1); |
434 |
|
432 |
|
435 |
/* Reset all loop detection counters and stats */ |
433 |
/* Reset all loop detection counters and stats */ |
436 |
for (i = 0; i < NG_BRIDGE_MAX_LINKS; i++) { |
434 |
for (i = 0; i < priv->maxLinks; i++) { |
437 |
if (priv->links[i] == NULL) |
435 |
if (priv->links[i] == NULL) |
438 |
continue; |
436 |
continue; |
439 |
priv->links[i]->loopCount = 0; |
437 |
priv->links[i]->loopCount = 0; |
Lines 455-461
Link Here
|
455 |
break; |
453 |
break; |
456 |
} |
454 |
} |
457 |
linkNum = *((u_int32_t *)msg->data); |
455 |
linkNum = *((u_int32_t *)msg->data); |
458 |
if (linkNum < 0 || linkNum >= NG_BRIDGE_MAX_LINKS) { |
456 |
if (linkNum < 0 || linkNum >= priv->maxLinks) { |
459 |
error = EINVAL; |
457 |
error = EINVAL; |
460 |
break; |
458 |
break; |
461 |
} |
459 |
} |
Lines 539-545
Link Here
|
539 |
NGI_GET_M(item, m); |
537 |
NGI_GET_M(item, m); |
540 |
/* Get link number */ |
538 |
/* Get link number */ |
541 |
linkNum = (intptr_t)NG_HOOK_PRIVATE(hook); |
539 |
linkNum = (intptr_t)NG_HOOK_PRIVATE(hook); |
542 |
KASSERT(linkNum >= 0 && linkNum < NG_BRIDGE_MAX_LINKS, |
540 |
KASSERT(linkNum >= 0 && linkNum < priv->maxLinks, |
543 |
("%s: linkNum=%u", __func__, linkNum)); |
541 |
("%s: linkNum=%u", __func__, linkNum)); |
544 |
link = priv->links[linkNum]; |
542 |
link = priv->links[linkNum]; |
545 |
KASSERT(link != NULL, ("%s: link%d null", __func__, linkNum)); |
543 |
KASSERT(link != NULL, ("%s: link%d null", __func__, linkNum)); |
Lines 779-784
Link Here
|
779 |
ng_uncallout(&priv->timer, node); |
777 |
ng_uncallout(&priv->timer, node); |
780 |
NG_NODE_SET_PRIVATE(node, NULL); |
778 |
NG_NODE_SET_PRIVATE(node, NULL); |
781 |
NG_NODE_UNREF(node); |
779 |
NG_NODE_UNREF(node); |
|
|
780 |
free(priv->links, M_NETGRAPH_BRIDGE); |
782 |
free(priv->tab, M_NETGRAPH_BRIDGE); |
781 |
free(priv->tab, M_NETGRAPH_BRIDGE); |
783 |
free(priv, M_NETGRAPH_BRIDGE); |
782 |
free(priv, M_NETGRAPH_BRIDGE); |
784 |
return (0); |
783 |
return (0); |
Lines 795-801
Link Here
|
795 |
|
794 |
|
796 |
/* Get link number */ |
795 |
/* Get link number */ |
797 |
linkNum = (intptr_t)NG_HOOK_PRIVATE(hook); |
796 |
linkNum = (intptr_t)NG_HOOK_PRIVATE(hook); |
798 |
KASSERT(linkNum >= 0 && linkNum < NG_BRIDGE_MAX_LINKS, |
797 |
KASSERT(linkNum >= 0 && linkNum < priv->maxLinks, |
799 |
("%s: linkNum=%u", __func__, linkNum)); |
798 |
("%s: linkNum=%u", __func__, linkNum)); |
800 |
|
799 |
|
801 |
/* Remove all hosts associated with this link */ |
800 |
/* Remove all hosts associated with this link */ |
Lines 944-949
Link Here
|
944 |
******************************************************************/ |
943 |
******************************************************************/ |
945 |
|
944 |
|
946 |
/* |
945 |
/* |
|
|
946 |
* Expand table of links, if necessary |
947 |
*/ |
948 |
static int |
949 |
ng_bridge_morelinks(node_p node, int linkNum) |
950 |
{ |
951 |
priv_p priv = NG_NODE_PRIVATE(node); |
952 |
int newsize = priv->maxLinks + NG_BRIDGE_INC_LINKS; |
953 |
void * newp; |
954 |
|
955 |
if (linkNum >= newsize || linkNum < 0) |
956 |
return (EINVAL); |
957 |
|
958 |
if (linkNum < priv->maxLinks) |
959 |
return 0; |
960 |
|
961 |
newp = realloc(priv->links, |
962 |
newsize * sizeof(*priv->links), |
963 |
M_NETGRAPH_BRIDGE, M_WAITOK | M_ZERO); |
964 |
if(newp == NULL) /* old array intact */ |
965 |
return (ENOMEM); |
966 |
|
967 |
priv->links = newp; |
968 |
priv->maxLinks = newsize; |
969 |
return 0; |
970 |
} |
971 |
|
972 |
/* |
947 |
* Remove all hosts associated with a specific link from the hashtable. |
973 |
* Remove all hosts associated with a specific link from the hashtable. |
948 |
* If linkNum == -1, then remove all hosts in the table. |
974 |
* If linkNum == -1, then remove all hosts in the table. |
949 |
*/ |
975 |
*/ |
Lines 1015-1021
Link Here
|
1015 |
ng_bridge_rehash(priv); |
1041 |
ng_bridge_rehash(priv); |
1016 |
|
1042 |
|
1017 |
/* Decrease loop counter on muted looped back links */ |
1043 |
/* Decrease loop counter on muted looped back links */ |
1018 |
for (counter = linkNum = 0; linkNum < NG_BRIDGE_MAX_LINKS; linkNum++) { |
1044 |
for (counter = linkNum = 0; linkNum < priv->maxLinks; linkNum++) { |
1019 |
struct ng_bridge_link *const link = priv->links[linkNum]; |
1045 |
struct ng_bridge_link *const link = priv->links[linkNum]; |
1020 |
|
1046 |
|
1021 |
if (link != NULL) { |
1047 |
if (link != NULL) { |