pairmove() patch with multiple vendor-specific attributes

Geoffrey D. Bennett g at netcraft.com.au
Thu Jul 13 16:05:09 CEST 2006


Hi there,

I'm using rlm_perl to add custom reply attributes, but there's a
problem when I want to return multiple instances of the same
attribute, eg.:

  Cisco-AVPair=lcp:interface-config=service-policy output RATE-512
  Cisco-AVPair=lcp:interface-config=service-policy input RATE-128

rlm_perl supports this (it looks out for arrayrefs) but rlmperl_call()
calls pairmove() to put the attributes into the reply:

        if ((get_hv_content(rad_reply_hv, &vp)) > 0 ) {
                pairmove(&request->reply->vps, &vp);
                pairfree(&vp);
        }

and pairmove() will "move attributes from one list to the other if not
already present".  Unfortunately, this means that only the first
Cisco-AVPair ends up getting moved.

I've attached a patch which makes pairmove() move all vendor-specific
attributes.  It works for me.  The patch says 1.1.1, but it applies to
1.1.2 as well (untested, but I guess it should work -- lib/valuepair.c
and rlm_perl.c look similar enough).

Thanks,
-- 
Geoffrey D. Bennett, RHCE, RHCX               mailto:g at netcraft.com.au
Senior Systems Engineer                          sip:g at netcraft.com.au
NetCraft Australia Pty Ltd        http://www.netcraft.com.au/geoffrey/
-------------- next part --------------
--- freeradius-1.1.1/src/lib/valuepair.c.orig	2006-07-13 23:32:25.000000000 +1000
+++ freeradius-1.1.1/src/lib/valuepair.c	2006-07-13 23:40:38.000000000 +1000
@@ -313,11 +313,14 @@
 		/*
 		 *	If the attribute is already present in "to",
 		 *	do not move it from "from" to "to". We make
-		 *	an exception for "Hint" which can appear multiple
+		 *	an exception for "Hint", "Framed-Route", and
+		 *	vendor attributes which can appear multiple
 		 *	times, and we never move "Fall-Through".
 		 */
 		if (i->attribute == PW_FALL_THROUGH ||
-		    (i->attribute != PW_HINT && i->attribute != PW_FRAMED_ROUTE)) {
+		    (i->attribute != PW_HINT &&
+		     i->attribute != PW_FRAMED_ROUTE &&
+		     (i->attribute >> 16) == 0)) {
 
 			found = pairfind(*to, i->attribute);
 			switch (i->operator) {


More information about the Freeradius-Devel mailing list