Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
White Rabbit Switch - Software
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
86
Issues
86
List
Board
Labels
Milestones
Merge Requests
4
Merge Requests
4
CI / CD
CI / CD
Pipelines
Schedules
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
White Rabbit Switch - Software
Commits
8684bfa2
Commit
8684bfa2
authored
Oct 14, 2020
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rvlan: support a list of servers
Signed-off-by:
Alessandro Rubini
<
rubini@gnudd.com
>
parent
aa679b1e
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
88 additions
and
22 deletions
+88
-22
radiusvlan.c
userspace/tools/radiusvlan.c
+88
-22
No files found.
userspace/tools/radiusvlan.c
View file @
8684bfa2
...
...
@@ -36,11 +36,13 @@ char *prgname; /* argv[0], for my laziness */
int
verbose
;
int
rvlan_pmask
=
~
0
;
int
rvlan_change_pending
;
/* wrsw_vlans must be called globally */
char
*
rvlan_radius_servers
;
/* strdup from config */
char
*
rvlan_radius_secret
;
unsigned
long
rvlan_server_fail_nr
;
int
rvlan_auth_vlan
,
rvlan_noauth_vlan
,
rvlan_obey_dotconfig
;
int
rvlan_gotsignal
;
struct
rvlan_radius_server
;
/* defined later */
struct
rvlan_dev
{
char
*
name
;
/* Allocated */
int
portnr
;
...
...
@@ -54,6 +56,7 @@ struct rvlan_dev {
unsigned
char
mac
[
ETH_ALEN
];
/* Own mac address */
char
radbuffer
[
10240
];
int
radbuffer_size
;
struct
rvlan_radius_server
*
server
;
struct
rvlan_dev
*
next
;
};
...
...
@@ -62,6 +65,7 @@ enum fsm_state {
RVLAN_DOWN
,
RVLAN_JUSTUP
,
RVLAN_SNIFF
,
RVLAN_RADCLIENT
,
RVLAN_AUTH
,
RVLAN_CONFIG
,
RVLAN_CONFIGURED
,
...
...
@@ -72,6 +76,7 @@ char *fsm_names[] = {
[
RVLAN_DOWN
]
=
"down"
,
[
RVLAN_JUSTUP
]
=
"justup"
,
[
RVLAN_SNIFF
]
=
"sniff"
,
[
RVLAN_RADCLIENT
]
=
"radclient"
,
[
RVLAN_AUTH
]
=
"auth"
,
[
RVLAN_CONFIG
]
=
"config"
,
[
RVLAN_CONFIGURED
]
=
"configured"
,
...
...
@@ -98,6 +103,64 @@ int rvlan_mac_is_local(uint8_t *address)
return
0
;
}
/* Another list: all the servers */
struct
rvlan_radius_server
{
char
*
addr
;
unsigned
long
last_failure
;
struct
rvlan_radius_server
*
next
;
};
struct
rvlan_radius_server
*
servers
;
/* Create a list of servers */
int
rvlan_server_mklist
(
char
*
names
)
{
struct
rvlan_radius_server
*
new
,
*
last
=
NULL
;
char
*
comma
;
while
(
names
[
0
])
{
new
=
calloc
(
1
,
sizeof
(
*
new
));
if
(
!
new
)
return
-
1
;
comma
=
strchr
(
names
,
','
);
if
(
comma
)
*
comma
=
'\0'
;
new
->
addr
=
strdup
(
names
);
if
(
comma
)
names
=
comma
+
1
;
else
names
=
""
;
/* save at the end of the list, to preserve order */
if
(
last
)
{
last
->
next
=
new
;
last
=
new
;
}
else
{
servers
=
last
=
new
;
}
if
(
verbose
)
printf
(
"Radius server:
\"
%s
\"\n
"
,
new
->
addr
);
}
return
0
;
}
/* Report a server failure */
void
rvlan_server_failed
(
struct
rvlan_dev
*
dev
)
{
if
(
dev
->
server
)
dev
->
server
->
last_failure
=
++
rvlan_server_fail_nr
;
}
/* Return the best server */
struct
rvlan_radius_server
*
rvlan_server_get
(
void
)
{
struct
rvlan_radius_server
*
s
,
*
best
;
for
(
s
=
best
=
servers
;
s
;
s
=
s
->
next
)
if
(
s
->
last_failure
<
best
->
last_failure
)
best
=
s
;
return
best
;
}
/* Helper for calling the wrs_vlan executable */
int
rvlan_change_vlan
(
struct
rvlan_dev
*
dev
)
{
...
...
@@ -227,7 +290,14 @@ int rvlan_fsm(struct rvlan_dev *dev, fd_set *rdset)
frame
[
12
]
<<
8
|
frame
[
13
],
dev
->
peer_mac
);
close
(
dev
->
poll_fd
);
dev
->
poll_fd
=
-
1
;
dev
->
fsm_state
=
RVLAN_RADCLIENT
;
/* and fall through */
case
RVLAN_RADCLIENT
:
dev
->
server
=
rvlan_server_get
();
if
(
verbose
)
printf
(
"dev %s queries server %s
\n
"
,
dev
->
name
,
dev
->
server
->
addr
);
/*
* Now, fire the radclient process before changing state
*/
...
...
@@ -249,9 +319,10 @@ int rvlan_fsm(struct rvlan_dev *dev, fd_set *rdset)
dup
(
pipe1
[
1
]);
close
(
pipe1
[
1
]);
close
(
STDERR_FILENO
);
dup
(
STDOUT_FILENO
);
/* radclient <IP> auth <SECRET> */
execlp
(
"radclient"
,
"radclient"
,
rvlan_radius_servers
,
"auth"
,
rvlan_radius_secret
,
NULL
);
execlp
(
"radclient"
,
"radclient"
,
dev
->
server
->
addr
,
"auth"
,
rvlan_radius_secret
,
NULL
);
fprintf
(
stderr
,
"%s: exec(): %s
\n
"
,
prgname
,
strerror
(
errno
));
exit
(
1
);
...
...
@@ -330,6 +401,15 @@ int rvlan_fsm(struct rvlan_dev *dev, fd_set *rdset)
fclose
(
f
);
}
}
/* See if there was a server error */
if
(
WEXITSTATUS
(
i
)
!=
0
&&
!
strncmp
(
dev
->
radbuffer
,
"radclient"
,
9
))
{
rvlan_server_failed
(
dev
);
if
(
verbose
)
printf
(
"%s: server failed
\n
"
,
dev
->
name
);
dev
->
fsm_state
=
RVLAN_RADCLIENT
;
/* and go back */
break
;
}
/* And parse the result */
dev
->
chosen_vlan
=
rvlan_noauth_vlan
;
...
...
@@ -725,6 +805,7 @@ int main(int argc, char **argv)
int
sock
;
char
*
rvlan_dev_prefix
=
"wri"
;
char
*
dotconfig
=
"/wr/etc/dot-config"
;
char
*
servers
;
prgname
=
argv
[
0
];
verbose
=
getenv
(
"RVLAN_VERBOSE"
)
!=
NULL
;
...
...
@@ -741,7 +822,6 @@ int main(int argc, char **argv)
if
(
IS_WRS
)
{
int
i
,
mask
;
char
*
s
;
char
*
comma
;
i
=
libwr_cfg_read_file
(
dotconfig
);
if
(
i
<
0
)
{
...
...
@@ -784,28 +864,14 @@ int main(int argc, char **argv)
if
(
s
&&
s
[
0
]
==
'y'
)
rvlan_obey_dotconfig
=
1
;
rvlan_radius_
servers
=
libwr_cfg_get
(
"RVLAN_RADIUS_SERVERS"
);
servers
=
libwr_cfg_get
(
"RVLAN_RADIUS_SERVERS"
);
rvlan_radius_secret
=
libwr_cfg_get
(
"RVLAN_RADIUS_SECRET"
);
if
(
!
rvlan_radius_
servers
||
!
rvlan_radius_secret
)
{
if
(
!
servers
||
!
rvlan_radius_secret
)
{
fprintf
(
stderr
,
"%s: missing dot-config items
\n
"
,
argv
[
0
]);
exit
(
1
);
}
rvlan_radius_servers
=
strdup
(
rvlan_radius_servers
);
if
(
!
rvlan_radius_servers
)
{
fprintf
(
stderr
,
"%s: strdup(): %s
\n
"
,
argv
[
0
],
strerror
(
errno
));
exit
(
1
);
}
comma
=
strchr
(
rvlan_radius_servers
,
','
);
if
(
comma
)
{
*
comma
=
'\0'
;
fprintf
(
stderr
,
"%s: Warning: using first radius "
"server only (
\"
%s
\"
)
\n
"
,
argv
[
0
],
rvlan_radius_servers
);
}
if
(
0
)
libwr_cfg_dump
(
stdout
);
rvlan_server_mklist
(
servers
);
}
/* Create a list of "wr" devices */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment