-
Notifications
You must be signed in to change notification settings - Fork 231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PPP ifname enhanced #289
PPP ifname enhanced #289
Conversation
@paulusmack: What do you think? |
I hope it will not take 2-3 years to try to merge the PR. 😂. |
First off, the commit messages are quite inadequate and don't even have a signoff (I wonder how we lost the automatic check for the signoff). Please read Submitting-patches.md. The "PPP enhanced ifname" commit definitely needs at least 2 or 3 paragraphs explaining what you are doing as well as any useful information on why you implemented it the way you did. Is there a reason for not supporting the new format on Solaris? Is it just that you don't know if regcomp etc. would be available on Solaris? There are 3 big blocks of code added, of which two seem to be just about extracting the unit number (ifunit) that was put on. Why can't those two places just use 'ifunit' instead of having to do all that complicated parsing using regular expressions? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whilst ongoing with this, how about %u to replace with the authenticated username? This would require some limiting such that if the usename results in names longer than 15 characters the overall interface name gets stripped down, eg, let's say I auth as "jkroon" (that's 6 chars), and ifname is specified as pppd-vpn-%u-%d and the unit number is 999 then that gives pppd-vpn-jkroon-999 (19 chars) that will need to be trimmed to pppd-vpn-jk-999, but if unit number is 1, then it's fine to use pppd-vpn-jkro-1 for example.
This does get quite complex, so really just a suggestion, this is of benefit as it stands either way and I support the idea regardless.
Hi @paulusmack, Where exactly is this part you are refering at? Is about radius.c? I don't get it. |
It was another discussing to add the main interface from where the connection is comming. Let's merge this patch and we can add new features for other thinks. |
If you are talking about radius.c part, I could ask the same why in the first place we had this:
What I did was to expand this sscanf to a more userfiendly regex to extract the port from the name of the interface. I think in radius.c you will not get ifunit here. This ifunit is allocated for each new interface connected. Afterwards you will lose this "ifunit" in radius.c. Could you please be more specific? |
Yea... seems that usage of regular expression for implementing %fmt format is overkill and current implementation is not easily extendable for e.g. Is there any particular reason why usage of regular expression was chosen instead of classic %fmt string processing like it is implemented in most printf-based function implementation? I'm just curious and asking as probably I do not see some important details... And for me it looks like usage of e.g. |
Hi @pali, I'm not a very good in coding. I like doing stuff and I'm trying to add some features to the software in my knowledge limits of my coding. First implementation I did it was with strcmp. Then somebody came with the idea to use regex. I rewrote the code using regex. |
May it not be a better idea to get the unit number passed in then somehow? I fully agree that naming the interfaces by function makes a lot of sense, eg, ppp-vpn-%d (for vpn clients), and ppp-red-%d (for external uplinks) which would greatly simplify firewalling since now we can match on ppp-vpn-+ in iptables/netfilter to match all VPN connections. If one could add the auth username too, I could take this further to say vpn-%.u-%d where the . could indicate trim this field if the resulting name is too long (>15 chars), or one could (conceivable for the moment) force %u to be trimmed. This does introduce corner cases for firewalling though ... eg, using jkroon (6 chars) and ppp-vpn-%u-%d (ppp-vpn-jkroon- is 15 chars, so depending on the unit number in use ... this can end up as ppp-vpn-jkroo-X, ppp-vpn-jkro-XX or ppp-vpn-jkr-XXX - or if we go unit number >= 1000 even shorter). @EasyDevNet - I could also take a swing at this specific patch for you if you don't come right or prefer. |
In nftables you can specify wildcard
Well, sometimes I'm using it :-)
I would suggest you to look at how to write %fmt-processing function in extendable-way if you have never done it before or have not see it. There is common pattern how to do it. E.g. ppp code has also one %fmt processing function, look: Lines 134 to 246 in 93fd8a0
Basically you need to read input %fmt string from left to right and put read character into output buffer. When you find If needed, I can help with implementation (I have sent more patches to ppp). Just I do not want to have too many open pull requests :-) (I have there one big which seems to take more time to review). |
Hi, Then you need to think how you will implement in radius.c the part of the ifunit extraction. |
@EasyNetDev I'm looking at radius.c change. This parsing is used only in get_client_port() function which is used only for setting rstate.client_port and moreover marked as hack: ppp/pppd/plugins/radius/radius.c Lines 277 to 279 in 86936b6
Then rstate.client_port is used only as second argument for function rc_auth_using_server() which is used for setting
ppp radius plugin has some configuration options how is RFC2865 Radius NAS-Port calculated: ppp/pppd/plugins/radius/radius.c Lines 64 to 72 in 86936b6
So I think that for (default) option map-to-ifname, it should retrieve number directly from pppd (same number which you use for |
Anyway, when setting NAS-Port it is suggested to set also appropriate NAS-Port-Type. Current list of all port types is managed by IANA: https://www.iana.org/assignments/radius-types/radius-types.xhtml#radius-types-13 |
So in my opinion this code ppp/pppd/plugins/radius/radius.c Lines 277 to 279 in 86936b6
should contain something like this. First check type of connection:
And then based on connection type set NAS-Port and NAS-Port-Type:
Just this is my opinion how it should be set. |
Anyway, one very important thing! There are two numeric identifiers associated with every ppp network interface. One is PPP unit id (this is IIRC unique identifier for kernel lifetime associated only for ppp network interfaces in ascending order) and another one kernel network interface id (again unique in system across all network interfaces, not only ppp; this is visible in Also interface name may contain some number, lot of times people put them at the end, e.g. eth4 or ppp2. And this number is in most cases different from above two numbers. So beware when talking about interface number, it may be PPP unit id, it may be kernel interface number or it may be number at the end of interface name. (Not mentioning that there is also list of PPP channel numbers which may change during existence of ppp connection and which are and must be different than PPP unit id :D) |
@EasyNetDev: If you need some more information or help with something, let me know. |
Hi @pali, From what I saw in the code, ppp ifunit is returned by ioctl when by the creation of the new PPP interface usign ioctl function, here:
So this is not the interface network id. Is just the PPP driver allocation id. That's why. when you sent to RADIUS the auth or post-auth info, this is the ID which is sent also, and not interface network id. More logical is this ID than the interface network id, because PPP can reallocate unsed IDs. Example, you have ppp0, ppp1, ppp2, ppp3. Then ppp1 is disconnected and then another client is connecting. PPP will allocate ppp1 again for the new client, but the interface network id will increase, obviously. radius.c is very old file. The history of this file seems to be from 2002 or 2008. Using %fmt I guess is working the same. I don't know what is the performance penalities between these 2 aproches. If everybody thinks is a good idea to implement %fmt solution instead regex, we can give a try. Regex is alread in libc, no need to build a lot of code, again, beeing in my opinion the fastest end easieast solution to implement this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are two approaches in radius.c for the NAS-Port (which I think must be an int based on the freeradius dictionary: dictionary.rfc2865:ATTRIBUTE NAS-Port 5 integer).
In the case where we do have a serial interface (tty), eg, /dev/ttyS0 or the like, using NAS-Port == 0 along with some sensible NAS-Port-Type (Sync?) would be great. There are various options in dictionary.rfc2865, and a few from dictionary.iana files. If we can know for a fact it's ISDN (there are modules in asterisk that allows this) then we can use the ISDN NAS-Port-Type for example. So it's conceivable that we can map the tty name if it's available (find any trailing integer to the ttyname, default to Sync port type, unless radius config option says to use something else).
For L2TP and PPTP dial-ins my personal feeling says using probably Async with ppp unit (not network) id. Ie, the int that's intended to go into %d for the patch under discussion here.
On Wireless for example, I'm not sure what MT does, but in such a case I would hint that Port-Type should be Ethernet, with the Port being some interface ID, with the Calling-Station-ID eventually finalizing the unique triplet (ie, the combination of NAS-Port-Type, NAS-Port and Calling-Station-ID is unique per session). To be more precise, this is an example (obfuscated slightly, indicated with $), of an auth request we're receiving from a MT for a PPPoE connection:
Packet-Type = Access-Request
Service-Type = Framed-User
Framed-Protocol = PPP
NAS-Port = 15823683
NAS-Port-Type = Ethernet
User-Name = "$user@$realm"
Calling-Station-Id = "11:22:33:44:55:66"
Called-Station-Id = "service-name"
NAS-Port-Id = "interface-name"
MS-CHAP-Domain = "$realm"
Acct-Session-Id = "$session_id"
MS-CHAP-Challenge = $0xXX..XX
MS-CHAP2-Response = $0xXX..XX
NAS-Identifier = "$routers_system_name"
NAS-IP-Address = $router_ip
Mikrotik-Realm = "$realm"
Timestamp = 1625101032
NAS-Port here seems to be the network identifier (we don't see recurring identifiers for successive access-requests).
Using the ppp unit number we can have repeats (eg, ppp0 disconnects, then some other ppp0 reconnects). So it would be great to be able to configure what gets sent here, along with having semi sane defaults here. This however starts moving into a patch for radius which IMHO should be separate, so either that should be a pre-requisite for the naming patch, or we should make minimal adjustments to radius.c now.
In radius.c the one approach currently tries to map the tty name, this shouldn't change, the other approach assumed ppp%d format here, so my suggestion is to rather somehow extract the ppp unit number in that case rather than trying to parse the interface name. If needed. This is already a bug since it's assuming ppp%d in get_client_port(), when it should probably rather use PPP_DRV_NAME (eg, sscanf(ifname, PPP_DRV_NAME "%d", &port) ... however, looking at the way "%s%d", PPP_DRV_NAME, ?? is used, it suggests PPP_DRV_NAME could legally contain % signs, so care should be taken to safeguard this (and I have no ideas how to do that compile time). There is also a potential bug in sys-solaris.c on this whilst I see this:
sys-solaris.c: slprintf(ifr.ifr_name, sizeof(ifr.ifr_name), PPP_DRV_NAME "%d", ifunit);
All other code uses the *printf(..., "...%s...", ... PPP_DRV_NAME, ...) construct for this.
{ "ifname", o_string, req_ifname, | ||
"Set PPP interface name", | ||
"Set PPP interface name. If format is like ppp%%d / pppoe%%d / l2tp%%d, where %%d will be replaced by unit number. Linux Only.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
%%d will be replaced with the PPP unit number (Linux Only).
Just feels more concise for me.
pppd/plugins/radius/dict.c
Outdated
@@ -150,7 +150,7 @@ int rc_read_dictionary (char *filename) | |||
{ | |||
type = PW_TYPE_INTEGER; | |||
} | |||
else if (strcmp (typestr, "ipaddr") == 0) | |||
else if (strcmp (typestr, "ipaddr") == 0 || strcmp (typestr, "ipv4addr") == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense to have this change as it's own PR to be honest. This is good to go and makes zero sense to have this blocked whilst sorting out the rest of the PR.
%d in the end of the string pppd will add ppp unit and will create a new | ||
interface named like pppoe0, l2tp1, ptpp3. This is valid only for LINUX. | ||
If is used without %d and the interface name is already in use, or if the | ||
name cannot be used for any other reason, pppd will terminate. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The following format characters are supported:
%% - literal %.
%d - Linux only: Replace with the ppp unit number.
%u - replace with the authenticated username (will be trimmed automatically if the resulting interface name is too long).
@@ -667,6 +668,19 @@ static int make_ppp_unit(void) | |||
{ | |||
int x, flags; | |||
|
|||
// Variable to create regex | |||
regex_t *regex; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This need not be a pointer, can be allocated on-stack (it's small enough in my opinion at 64 bytes).
// Variable to create regex | ||
regex_t *regex; | ||
|
||
regex = malloc(sizeof(regex_t)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not seeing associated free().
error("Couldn't rename interface %s to %s: %m", old_ifname, new_ifname); | ||
else | ||
info("Renamed interface %s to %s", old_ifname, new_ifname); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good except I'm also of the opinion to rather use %fmt expansion,we can flag if/where %u gets used (not even sure if it's available yet at this point for shortening, start/stop char indexes), and I suggest only error'ing out if the resulting name is too long (eventually if we can shorten, only error after shortening has failed). Also, we may want to split %U (full username vs %u as username without realm kind of thing, I know in some cases there are potential issues with realm here in format \realm\username vs username@realm). So for now I suggest we ignore %u as an initial patch. There is technically no reason to disallow multiple instances of %d in the if name, although this would be weird.
So if your aim is to retrieve ppp unit number, why you are doing it in such complicated way (build regex and extract it from interface name)? If I'm looking at the code correctly, this ppp unit number is already stored in (global) variable
I proposed %fmt parsing because it is easy extendable. Seems that this functionality to extend template/patterns for interface name is interesting for more people, e.g. @jkroonza had idea about username and I would like to see also other things (like name of ethernet interface). So in future it would be relatively easy to implement new %fmt for these things as opposite to regex implementation which is hard to extend for a new functionality (without reimplementing it again). And because lot of people have different taste how interface should be named it is possible that more other people would be interested by providing new patches for new %fmt formats... Plus bonus for %fmt should be also working Solaris support as in this %fmt processing implementation is nothing platform specific. (I know that testing is harder, but there would be not need to hide this code under linux guards) |
@jkroonza: sync vs async is reference to type of tty/modem. In most cases people use async, e.g. RS232, UART. sync type is e.g. HDLC. Also if you want to use pppd in sync type you have to specify "sync" option to pppd. otherwise pppd is running in async mode. So choosing sync vs async NAS-Port-Type is simple, user specify to pppd which mode uses (I described it in comment #289 (comment)). I think that people in these days do not run pppd over serial interface or modem too often, so do not care about sync vs async mode. |
Gotcha. Perhaps we need to split this PR/discussion into two (not sure how to do that on github) where the current deals specifically with the ifname change, and a separate discussion for improving the radius mechanism? |
Github does not support discussion split. The only option is to open a new "issue" and continue discussion there. |
I think that for this patch, we should be changing get_client_port() in the radius code to just do 'return ifunit'. Then somebody should do another patch on top to make that more intelligent if necessary. Also, since the code that does the %d substitution in the interface name seems to be needed in two places, it should be factored out into a function. That way if there is a bug in it, it will only need to be fixed in one place. |
This is now a real mess, with merges from my repository with conflicts checked in, and then only later resolved in other commits. That will break bisection. Also, none of the requested changes have been made; for example get_client_port() is still doing all the complicated regex gunk. If you still want this in, please re-do it as a clean commit (or series of commits) without merges. |
Hi @Neustradamus , I was able to merge the patch with latest version of pppd. Hope this time will be accepted. |
…so plugin (#304) Backward compatibility symlink is there already for one ppp release. Remove it for next ppp release to not conflict with real rp-pppoe.so plugin. So both ppp's pppoe.so and rp's rp-pppoe.so plugins can be installed together. Now when conversion to automake was done, it is a good time to drop this problematic symlink from default installation. Signed-off-by: Pali Rohár <[email protected]> Signed-off-by: Adrian Ban <[email protected]>
Options that specify --with-logfile-dir, or --with-plugin-dir, or --with-runtime-dir needs to be specified using AC_ARG_WITH, not AC_ARG_ENABLE. If you try to specify --without-openssl, then the conditions should be tested against = "xyes". There is a case where the option is either blank or is set to "xno" and the former case wasn't properly handled. Signed-off-by: Eivind Næss <[email protected]> Signed-off-by: Adrian Ban <[email protected]>
… option Signed-off-by: Pali Rohár <[email protected]> Signed-off-by: Adrian Ban <[email protected]>
…ery2() pppoe-discovery.c needs to call only the first phase of discovery. Signed-off-by: Pali Rohár <[email protected]> Signed-off-by: Adrian Ban <[email protected]>
…ry.c code Signed-off-by: Pali Rohár <[email protected]> Signed-off-by: Adrian Ban <[email protected]>
…bose option is set Signed-off-by: Pali Rohár <[email protected]> Signed-off-by: Adrian Ban <[email protected]>
Signed-off-by: Pali Rohár <[email protected]> Signed-off-by: Adrian Ban <[email protected]>
…intf() Signed-off-by: Pali Rohár <[email protected]> Signed-off-by: Adrian Ban <[email protected]>
…e plugin code Signed-off-by: Pali Rohár <[email protected]> Signed-off-by: Adrian Ban <[email protected]>
…cters This adds logic to pppoe_printpkt to print text fields as hex if the field contains any non-printable characters. This is so that a malicious, buggy or hacked access concentrator can't cause us to send non-printing characters to syslog. Signed-off-by: Paul Mackerras <[email protected]> Signed-off-by: Adrian Ban <[email protected]>
….15. (#327) Signed-off-by: RICCIARDI-Adrien <[email protected]> Signed-off-by: Adrian Ban <[email protected]>
@EasyNetDev: Thanks for your comeback. Have you looked all @pali and @jkroonza comments? Hope that @paulusmack will merge the new PR soon. |
@EasyNetDev: Do not forget to sign in your new PR when you will publish. Error in the current closed PR: https://github.com/ppp-project/ppp/pull/289/checks Thanks in advance. |
@EasyNetDev: Have you a problem to create the new PR? :/ |
@paulusmack: Can you look the @EasyNetDev commits? He had a problem with Git :/ It is good or not? |
@EasyNetDev: It is not possible to create a new PR? I think it is the best solution... |
Hi Neustradamus,
I'm working to this patch to implemetn fmt format and skip regexp.
Maybe these days I will be able to push the patch.
Kind regards,
…On 08/07/2022 03:37, Neustradamus wrote:
@EasyNetDev <https://github.com/EasyNetDev>: It is not possible to
create a new PR?
I think it is the best solution...
—
Reply to this email directly, view it on GitHub
<#289 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAN5CKH7K2JMKHRMXSKZPX3VS6A43ANCNFSM47HLDFHA>.
You are receiving this because you were mentioned.Message ID:
***@***.***>
--
Adrian Ban
Tel: +40788388190
Web: www.easynet.dev <https://www.easynet.dev>
|
@EasyNetDev: Have you looked? |
Hi Neustradamus. I'm finishing the part with %fmt. I still didn't understood very wheel how we should implement radius.c problem. I saw the comments, but the programming side regarding ioctl and so on are over my knowledge. |
@enaess and others: What do you think about last @EasyNetDev comment? |
Which commit? I see 48 here. Maybe this PR needs to rebase? |
@enaess: sorry : comments! |
This PR has been closed, with the promise of a new PR, perhaps this should be handled there? If an update is forthcoming? |
@EasyNetDev would 0d12ca7 (Part of PR #367 suit your needs? |
The original commit from @EasyNetDev in this PR was: The problem was when there was other merged PR... |
@EasyNetDev: What do you think? We wait you for a new PPP version. |
@Neustradamus I am not sure if this PR or fix for this problem should hold back a version 2.5 release. |
I believe that renaming the interface externally (commit 0d12ca7) may be sufficient already, that said, an internal to pppd solution may well be very nice too, external ability to rename may well provide much more flexibility. I do agree that this should not hold back a 2.5 release. |
Added support for PPP custom interface name under Linux.
Closing #285 and #116.