* Re: [PATCH net-next 1/7] lwt: Add net to build_state argument
From: kbuild test robot @ 2016-09-15 0:17 UTC (permalink / raw)
To: Tom Herbert; +Cc: kbuild-all, davem, netdev, tgraf, roopa, kernel-team
In-Reply-To: <1473895376-347096-2-git-send-email-tom@herbertland.com>
[-- Attachment #1: Type: text/plain, Size: 1466 bytes --]
Hi Tom,
[auto build test ERROR on net-next/master]
url: https://github.com/0day-ci/linux/commits/Tom-Herbert/net-ILA-resolver-and-generic-resolver-backend/20160915-073357
config: i386-randconfig-x003-201637 (attached as .config)
compiler: gcc-6 (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
Note: the linux-review/Tom-Herbert/net-ILA-resolver-and-generic-resolver-backend/20160915-073357 HEAD ef54da9d3e09732810a23f283e0f8039fb18eede builds fine.
It only hurts bisectibility.
All errors (new ones prefixed by >>):
net/core/lwtunnel.c: In function 'lwtunnel_encap_str':
>> net/core/lwtunnel.c:42:7: error: 'LWTUNNEL_ENCAP_ILA_NOTIFY' undeclared (first use in this function)
case LWTUNNEL_ENCAP_ILA_NOTIFY:
^~~~~~~~~~~~~~~~~~~~~~~~~
net/core/lwtunnel.c:42:7: note: each undeclared identifier is reported only once for each function it appears in
vim +/LWTUNNEL_ENCAP_ILA_NOTIFY +42 net/core/lwtunnel.c
36 */
37 switch (encap_type) {
38 case LWTUNNEL_ENCAP_MPLS:
39 return "MPLS";
40 case LWTUNNEL_ENCAP_ILA:
41 return "ILA";
> 42 case LWTUNNEL_ENCAP_ILA_NOTIFY:
43 return "ILA_NOTIFY";
44 case LWTUNNEL_ENCAP_IP6:
45 case LWTUNNEL_ENCAP_IP:
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 23976 bytes --]
^ permalink raw reply
* Re: [RFC 2/3] staging: rtl8712: Change _LED_STATE enum in rtl871x driver to avoid conflicts with LED namespace
From: Larry Finger @ 2016-09-15 0:13 UTC (permalink / raw)
To: Zach Brown, f.fainelli
Cc: devel, florian.c.schilhabel, netdev, linux-kernel, mlindner
In-Reply-To: <1473890149-2066-3-git-send-email-zach.brown@ni.com>
On 09/14/2016 04:55 PM, Zach Brown wrote:
> Adding led support for phy causes namespace conflicts for some
> phy drivers.
>
> The rtl871 driver declared an enum for representing LED states. The enum
> contains constant LED_OFF which conflicted with declartation found in
> linux/leds.h. LED_OFF changed to LED_STATE_OFF
>
> Signed-off-by: Zach Brown <zach.brown@ni.com>
I have no objection to this change. My only substantive comment is that LED_ON
should also be changed to LED_STATE_ON, otherwise there might be another
namespace collision later. There is also a typo in the commit message. In
addition, staging driver patches should be sent to Greg KH.
Larry
> ---
> drivers/staging/rtl8712/rtl8712_led.c | 192 +++++++++++++++++-----------------
> 1 file changed, 96 insertions(+), 96 deletions(-)
>
> diff --git a/drivers/staging/rtl8712/rtl8712_led.c b/drivers/staging/rtl8712/rtl8712_led.c
> index 9055827..d53ad76 100644
> --- a/drivers/staging/rtl8712/rtl8712_led.c
> +++ b/drivers/staging/rtl8712/rtl8712_led.c
> @@ -52,7 +52,7 @@
> enum _LED_STATE_871x {
> LED_UNKNOWN = 0,
> LED_ON = 1,
> - LED_OFF = 2,
> + LED_STATE_OFF = 2,
> LED_BLINK_NORMAL = 3,
> LED_BLINK_SLOWLY = 4,
> LED_POWER_ON_BLINK = 5,
> @@ -92,7 +92,7 @@ static void InitLed871x(struct _adapter *padapter, struct LED_871x *pLed,
> nic = padapter->pnetdev;
> pLed->padapter = padapter;
> pLed->LedPin = LedPin;
> - pLed->CurrLedState = LED_OFF;
> + pLed->CurrLedState = LED_STATE_OFF;
> pLed->bLedOn = false;
> pLed->bLedBlinkInProgress = false;
> pLed->BlinkTimes = 0;
> @@ -249,7 +249,7 @@ static void SwLedBlink(struct LED_871x *pLed)
> } else {
> /* Assign LED state to toggle. */
> if (pLed->BlinkingLedState == LED_ON)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
>
> @@ -312,7 +312,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
> switch (pLed->CurrLedState) {
> case LED_BLINK_SLOWLY:
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -320,7 +320,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
> break;
> case LED_BLINK_NORMAL:
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -335,7 +335,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
> pLed->bLedLinkBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_NORMAL;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -344,7 +344,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
> pLed->bLedNoLinkBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_SLOWLY;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -353,7 +353,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
> pLed->bLedScanBlinkInProgress = false;
> } else {
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -369,7 +369,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
> pLed->bLedLinkBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_NORMAL;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -378,7 +378,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
> pLed->bLedNoLinkBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_SLOWLY;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -388,7 +388,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
> pLed->bLedBlinkInProgress = false;
> } else {
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -397,7 +397,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
> break;
> case LED_BLINK_WPS:
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -405,7 +405,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
> break;
> case LED_BLINK_WPS_STOP: /* WPS success */
> if (pLed->BlinkingLedState == LED_ON) {
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> mod_timer(&pLed->BlinkTimer, jiffies +
> msecs_to_jiffies(LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA));
> bStopBlinking = false;
> @@ -416,7 +416,7 @@ static void SwLedBlink1(struct LED_871x *pLed)
> pLed->bLedLinkBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_NORMAL;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -451,14 +451,14 @@ static void SwLedBlink2(struct LED_871x *pLed)
> pLed->BlinkingLedState = LED_ON;
> SwLedOn(padapter, pLed);
> } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
> - pLed->CurrLedState = LED_OFF;
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->CurrLedState = LED_STATE_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> SwLedOff(padapter, pLed);
> }
> pLed->bLedScanBlinkInProgress = false;
> } else {
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -475,14 +475,14 @@ static void SwLedBlink2(struct LED_871x *pLed)
> pLed->BlinkingLedState = LED_ON;
> SwLedOn(padapter, pLed);
> } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
> - pLed->CurrLedState = LED_OFF;
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->CurrLedState = LED_STATE_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> SwLedOff(padapter, pLed);
> }
> pLed->bLedBlinkInProgress = false;
> } else {
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -518,15 +518,15 @@ static void SwLedBlink3(struct LED_871x *pLed)
> if (!pLed->bLedOn)
> SwLedOn(padapter, pLed);
> } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
> - pLed->CurrLedState = LED_OFF;
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->CurrLedState = LED_STATE_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> if (pLed->bLedOn)
> SwLedOff(padapter, pLed);
> }
> pLed->bLedScanBlinkInProgress = false;
> } else {
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -544,15 +544,15 @@ static void SwLedBlink3(struct LED_871x *pLed)
> if (!pLed->bLedOn)
> SwLedOn(padapter, pLed);
> } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
> - pLed->CurrLedState = LED_OFF;
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->CurrLedState = LED_STATE_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> if (pLed->bLedOn)
> SwLedOff(padapter, pLed);
> }
> pLed->bLedBlinkInProgress = false;
> } else {
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -561,7 +561,7 @@ static void SwLedBlink3(struct LED_871x *pLed)
> break;
> case LED_BLINK_WPS:
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -569,7 +569,7 @@ static void SwLedBlink3(struct LED_871x *pLed)
> break;
> case LED_BLINK_WPS_STOP: /*WPS success*/
> if (pLed->BlinkingLedState == LED_ON) {
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> mod_timer(&pLed->BlinkTimer, jiffies +
> msecs_to_jiffies(LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA));
> bStopBlinking = false;
> @@ -602,14 +602,14 @@ static void SwLedBlink4(struct LED_871x *pLed)
> SwLedOff(padapter, pLed);
> if (!pLed1->bLedWPSBlinkInProgress &&
> pLed1->BlinkingLedState == LED_UNKNOWN) {
> - pLed1->BlinkingLedState = LED_OFF;
> - pLed1->CurrLedState = LED_OFF;
> + pLed1->BlinkingLedState = LED_STATE_OFF;
> + pLed1->CurrLedState = LED_STATE_OFF;
> SwLedOff(padapter, pLed1);
> }
> switch (pLed->CurrLedState) {
> case LED_BLINK_SLOWLY:
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -617,7 +617,7 @@ static void SwLedBlink4(struct LED_871x *pLed)
> break;
> case LED_BLINK_StartToBlink:
> if (pLed->bLedOn) {
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> mod_timer(&pLed->BlinkTimer, jiffies +
> msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
> } else {
> @@ -634,7 +634,7 @@ static void SwLedBlink4(struct LED_871x *pLed)
> pLed->bLedNoLinkBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_SLOWLY;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -642,7 +642,7 @@ static void SwLedBlink4(struct LED_871x *pLed)
> pLed->bLedScanBlinkInProgress = false;
> } else {
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -657,7 +657,7 @@ static void SwLedBlink4(struct LED_871x *pLed)
> pLed->bLedNoLinkBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_SLOWLY;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -665,7 +665,7 @@ static void SwLedBlink4(struct LED_871x *pLed)
> pLed->bLedBlinkInProgress = false;
> } else {
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -674,7 +674,7 @@ static void SwLedBlink4(struct LED_871x *pLed)
> break;
> case LED_BLINK_WPS:
> if (pLed->bLedOn) {
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> mod_timer(&pLed->BlinkTimer, jiffies +
> msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
> } else {
> @@ -685,7 +685,7 @@ static void SwLedBlink4(struct LED_871x *pLed)
> break;
> case LED_BLINK_WPS_STOP: /*WPS authentication fail*/
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -706,7 +706,7 @@ static void SwLedBlink4(struct LED_871x *pLed)
> msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
> } else {
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -742,7 +742,7 @@ static void SwLedBlink5(struct LED_871x *pLed)
> pLed->bLedScanBlinkInProgress = false;
> } else {
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -762,7 +762,7 @@ static void SwLedBlink5(struct LED_871x *pLed)
> pLed->bLedBlinkInProgress = false;
> } else {
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -797,7 +797,7 @@ static void SwLedBlink6(struct LED_871x *pLed)
> pLed->bLedBlinkInProgress = false;
> } else {
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -806,7 +806,7 @@ static void SwLedBlink6(struct LED_871x *pLed)
> break;
> case LED_BLINK_WPS:
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -908,7 +908,7 @@ static void SwLedControlMode1(struct _adapter *padapter,
> pLed->bLedNoLinkBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_SLOWLY;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -931,7 +931,7 @@ static void SwLedControlMode1(struct _adapter *padapter,
> pLed->bLedLinkBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_NORMAL;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -961,7 +961,7 @@ static void SwLedControlMode1(struct _adapter *padapter,
> pLed->CurrLedState = LED_SCAN_BLINK;
> pLed->BlinkTimes = 24;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -986,7 +986,7 @@ static void SwLedControlMode1(struct _adapter *padapter,
> pLed->CurrLedState = LED_TXRX_BLINK;
> pLed->BlinkTimes = 2;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -1016,7 +1016,7 @@ static void SwLedControlMode1(struct _adapter *padapter,
> pLed->bLedWPSBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_WPS;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -1046,7 +1046,7 @@ static void SwLedControlMode1(struct _adapter *padapter,
> pLed->bLedWPSBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_WPS_STOP;
> if (pLed->bLedOn) {
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> mod_timer(&pLed->BlinkTimer, jiffies +
> msecs_to_jiffies(LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA));
> } else {
> @@ -1063,15 +1063,15 @@ static void SwLedControlMode1(struct _adapter *padapter,
> pLed->bLedNoLinkBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_SLOWLY;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
> break;
> case LED_CTL_POWER_OFF:
> - pLed->CurrLedState = LED_OFF;
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->CurrLedState = LED_STATE_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> if (pLed->bLedNoLinkBlinkInProgress) {
> del_timer(&pLed->BlinkTimer);
> pLed->bLedNoLinkBlinkInProgress = false;
> @@ -1123,7 +1123,7 @@ static void SwLedControlMode2(struct _adapter *padapter,
> pLed->CurrLedState = LED_SCAN_BLINK;
> pLed->BlinkTimes = 24;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -1142,7 +1142,7 @@ static void SwLedControlMode2(struct _adapter *padapter,
> pLed->CurrLedState = LED_TXRX_BLINK;
> pLed->BlinkTimes = 2;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -1195,8 +1195,8 @@ static void SwLedControlMode2(struct _adapter *padapter,
>
> case LED_CTL_STOP_WPS_FAIL:
> pLed->bLedWPSBlinkInProgress = false;
> - pLed->CurrLedState = LED_OFF;
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->CurrLedState = LED_STATE_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> mod_timer(&pLed->BlinkTimer,
> jiffies + msecs_to_jiffies(0));
> break;
> @@ -1204,15 +1204,15 @@ static void SwLedControlMode2(struct _adapter *padapter,
> case LED_CTL_START_TO_LINK:
> case LED_CTL_NO_LINK:
> if (!IS_LED_BLINKING(pLed)) {
> - pLed->CurrLedState = LED_OFF;
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->CurrLedState = LED_STATE_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> mod_timer(&pLed->BlinkTimer,
> jiffies + msecs_to_jiffies(0));
> }
> break;
> case LED_CTL_POWER_OFF:
> - pLed->CurrLedState = LED_OFF;
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->CurrLedState = LED_STATE_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> if (pLed->bLedBlinkInProgress) {
> del_timer(&pLed->BlinkTimer);
> pLed->bLedBlinkInProgress = false;
> @@ -1255,7 +1255,7 @@ static void SwLedControlMode3(struct _adapter *padapter,
> pLed->CurrLedState = LED_SCAN_BLINK;
> pLed->BlinkTimes = 24;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -1273,7 +1273,7 @@ static void SwLedControlMode3(struct _adapter *padapter,
> pLed->CurrLedState = LED_TXRX_BLINK;
> pLed->BlinkTimes = 2;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -1310,7 +1310,7 @@ static void SwLedControlMode3(struct _adapter *padapter,
> pLed->bLedWPSBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_WPS;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -1326,7 +1326,7 @@ static void SwLedControlMode3(struct _adapter *padapter,
> }
> pLed->CurrLedState = LED_BLINK_WPS_STOP;
> if (pLed->bLedOn) {
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> mod_timer(&pLed->BlinkTimer, jiffies +
> msecs_to_jiffies(LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA));
> } else {
> @@ -1340,23 +1340,23 @@ static void SwLedControlMode3(struct _adapter *padapter,
> del_timer(&pLed->BlinkTimer);
> pLed->bLedWPSBlinkInProgress = false;
> }
> - pLed->CurrLedState = LED_OFF;
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->CurrLedState = LED_STATE_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> mod_timer(&pLed->BlinkTimer,
> jiffies + msecs_to_jiffies(0));
> break;
> case LED_CTL_START_TO_LINK:
> case LED_CTL_NO_LINK:
> if (!IS_LED_BLINKING(pLed)) {
> - pLed->CurrLedState = LED_OFF;
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->CurrLedState = LED_STATE_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> mod_timer(&pLed->BlinkTimer,
> jiffies + msecs_to_jiffies(0));
> }
> break;
> case LED_CTL_POWER_OFF:
> - pLed->CurrLedState = LED_OFF;
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->CurrLedState = LED_STATE_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> if (pLed->bLedBlinkInProgress) {
> del_timer(&pLed->BlinkTimer);
> pLed->bLedBlinkInProgress = false;
> @@ -1390,8 +1390,8 @@ static void SwLedControlMode4(struct _adapter *padapter,
> if (pLed1->bLedWPSBlinkInProgress) {
> pLed1->bLedWPSBlinkInProgress = false;
> del_timer(&pLed1->BlinkTimer);
> - pLed1->BlinkingLedState = LED_OFF;
> - pLed1->CurrLedState = LED_OFF;
> + pLed1->BlinkingLedState = LED_STATE_OFF;
> + pLed1->CurrLedState = LED_STATE_OFF;
> if (pLed1->bLedOn)
> mod_timer(&pLed->BlinkTimer,
> jiffies + msecs_to_jiffies(0));
> @@ -1411,7 +1411,7 @@ static void SwLedControlMode4(struct _adapter *padapter,
> pLed->bLedStartToLinkBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_StartToBlink;
> if (pLed->bLedOn) {
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> mod_timer(&pLed->BlinkTimer, jiffies +
> msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
> } else {
> @@ -1428,8 +1428,8 @@ static void SwLedControlMode4(struct _adapter *padapter,
> if (pLed1->bLedWPSBlinkInProgress) {
> pLed1->bLedWPSBlinkInProgress = false;
> del_timer(&pLed1->BlinkTimer);
> - pLed1->BlinkingLedState = LED_OFF;
> - pLed1->CurrLedState = LED_OFF;
> + pLed1->BlinkingLedState = LED_STATE_OFF;
> + pLed1->CurrLedState = LED_STATE_OFF;
> if (pLed1->bLedOn)
> mod_timer(&pLed->BlinkTimer,
> jiffies + msecs_to_jiffies(0));
> @@ -1446,7 +1446,7 @@ static void SwLedControlMode4(struct _adapter *padapter,
> pLed->bLedNoLinkBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_SLOWLY;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -1472,7 +1472,7 @@ static void SwLedControlMode4(struct _adapter *padapter,
> pLed->CurrLedState = LED_SCAN_BLINK;
> pLed->BlinkTimes = 24;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -1493,7 +1493,7 @@ static void SwLedControlMode4(struct _adapter *padapter,
> pLed->CurrLedState = LED_TXRX_BLINK;
> pLed->BlinkTimes = 2;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -1505,8 +1505,8 @@ static void SwLedControlMode4(struct _adapter *padapter,
> if (pLed1->bLedWPSBlinkInProgress) {
> pLed1->bLedWPSBlinkInProgress = false;
> del_timer(&pLed1->BlinkTimer);
> - pLed1->BlinkingLedState = LED_OFF;
> - pLed1->CurrLedState = LED_OFF;
> + pLed1->BlinkingLedState = LED_STATE_OFF;
> + pLed1->CurrLedState = LED_STATE_OFF;
> if (pLed1->bLedOn)
> mod_timer(&pLed->BlinkTimer,
> jiffies + msecs_to_jiffies(0));
> @@ -1527,7 +1527,7 @@ static void SwLedControlMode4(struct _adapter *padapter,
> pLed->bLedWPSBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_WPS;
> if (pLed->bLedOn) {
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> mod_timer(&pLed->BlinkTimer, jiffies +
> msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
> } else {
> @@ -1545,7 +1545,7 @@ static void SwLedControlMode4(struct _adapter *padapter,
> pLed->bLedNoLinkBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_SLOWLY;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -1559,7 +1559,7 @@ static void SwLedControlMode4(struct _adapter *padapter,
> pLed->bLedNoLinkBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_SLOWLY;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -1571,7 +1571,7 @@ static void SwLedControlMode4(struct _adapter *padapter,
> pLed1->bLedWPSBlinkInProgress = true;
> pLed1->CurrLedState = LED_BLINK_WPS_STOP;
> if (pLed1->bLedOn)
> - pLed1->BlinkingLedState = LED_OFF;
> + pLed1->BlinkingLedState = LED_STATE_OFF;
> else
> pLed1->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -1585,7 +1585,7 @@ static void SwLedControlMode4(struct _adapter *padapter,
> pLed->bLedNoLinkBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_SLOWLY;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -1598,15 +1598,15 @@ static void SwLedControlMode4(struct _adapter *padapter,
> pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP;
> pLed1->BlinkTimes = 10;
> if (pLed1->bLedOn)
> - pLed1->BlinkingLedState = LED_OFF;
> + pLed1->BlinkingLedState = LED_STATE_OFF;
> else
> pLed1->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
> break;
> case LED_CTL_POWER_OFF:
> - pLed->CurrLedState = LED_OFF;
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->CurrLedState = LED_STATE_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> if (pLed->bLedNoLinkBlinkInProgress) {
> del_timer(&pLed->BlinkTimer);
> pLed->bLedNoLinkBlinkInProgress = false;
> @@ -1679,7 +1679,7 @@ static void SwLedControlMode5(struct _adapter *padapter,
> pLed->CurrLedState = LED_SCAN_BLINK;
> pLed->BlinkTimes = 24;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -1695,7 +1695,7 @@ static void SwLedControlMode5(struct _adapter *padapter,
> pLed->CurrLedState = LED_TXRX_BLINK;
> pLed->BlinkTimes = 2;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -1703,8 +1703,8 @@ static void SwLedControlMode5(struct _adapter *padapter,
> }
> break;
> case LED_CTL_POWER_OFF:
> - pLed->CurrLedState = LED_OFF;
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->CurrLedState = LED_STATE_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> if (pLed->bLedBlinkInProgress) {
> del_timer(&pLed->BlinkTimer);
> pLed->bLedBlinkInProgress = false;
> @@ -1746,7 +1746,7 @@ static void SwLedControlMode6(struct _adapter *padapter,
> pLed->CurrLedState = LED_TXRX_BLINK;
> pLed->BlinkTimes = 2;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -1763,7 +1763,7 @@ static void SwLedControlMode6(struct _adapter *padapter,
> pLed->bLedWPSBlinkInProgress = true;
> pLed->CurrLedState = LED_BLINK_WPS;
> if (pLed->bLedOn)
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> else
> pLed->BlinkingLedState = LED_ON;
> mod_timer(&pLed->BlinkTimer, jiffies +
> @@ -1782,8 +1782,8 @@ static void SwLedControlMode6(struct _adapter *padapter,
> jiffies + msecs_to_jiffies(0));
> break;
> case LED_CTL_POWER_OFF:
> - pLed->CurrLedState = LED_OFF;
> - pLed->BlinkingLedState = LED_OFF;
> + pLed->CurrLedState = LED_STATE_OFF;
> + pLed->BlinkingLedState = LED_STATE_OFF;
> if (pLed->bLedBlinkInProgress) {
> del_timer(&pLed->BlinkTimer);
> pLed->bLedBlinkInProgress = false;
>
^ permalink raw reply
* RE: [PATCH v4 05/16] IB/pvrdma: Add functions for Verbs support
From: Adit Ranadive @ 2016-09-15 0:10 UTC (permalink / raw)
To: Christoph Hellwig
Cc: dledford@redhat.com, linux-rdma@vger.kernel.org, pv-drivers,
netdev@vger.kernel.org, linux-pci@vger.kernel.org,
Jorgen S. Hansen, Aditya Sarwade, George Zhang, Bryan Tan
In-Reply-To: <20160914124947.GA14616@infradead.org>
On Wed, Sep 14, 2016 at 05:49:50 -0700 Christoph Hellwig wrote:
> > + props->max_fmr = dev->dsr->caps.max_fmr;
> > + props->max_map_per_fmr = dev->dsr->caps.max_map_per_fmr;
>
> Please don't add FMR support to any new drivers.
We don't and our device reports these as 0. If you want me to more explicit I
can remove the zero'd out properties.
^ permalink raw reply
* Re: [PATCH v4 09/16] IB/pvrdma: Add support for Completion Queues
From: Adit Ranadive @ 2016-09-15 0:07 UTC (permalink / raw)
To: Yuval Shaia
Cc: dledford@redhat.com, linux-rdma@vger.kernel.org, pv-drivers,
netdev@vger.kernel.org, linux-pci@vger.kernel.org,
Jorgen S. Hansen, Aditya Sarwade, George Zhang, Bryan Tan
In-Reply-To: <20160914124321.GE15800@yuval-lap.uk.oracle.com>
On Wed, Sep 14, 2016 at 05:43:37 -0700, Yuval Shaia wrote:
> On Sun, Sep 11, 2016 at 09:49:19PM -0700, Adit Ranadive wrote:
> > +
> > +static int pvrdma_poll_one(struct pvrdma_cq *cq, struct pvrdma_qp
> **cur_qp,
> > + struct ib_wc *wc)
> > +{
> > + struct pvrdma_dev *dev = to_vdev(cq->ibcq.device);
> > + int has_data;
> > + unsigned int head;
> > + bool tried = false;
> > + struct pvrdma_cqe *cqe;
> > +
> > +retry:
> > + has_data = pvrdma_idx_ring_has_data(&cq->ring_state->rx,
> > + cq->ibcq.cqe, &head);
> > + if (has_data == 0) {
> > + if (tried)
> > + return -EAGAIN;
> > +
> > + /* Pass down POLL to give physical HCA a chance to poll. */
> > + pvrdma_write_uar_cq(dev, cq->cq_handle |
> PVRDMA_UAR_CQ_POLL);
> > +
> > + tried = true;
> > + goto retry;
> > + } else if (has_data == PVRDMA_INVALID_IDX) {
>
> I didn't went throw the entire life cycle of RX-ring's head and tail but you
> need to make sure that PVRDMA_INVALID_IDX error is recoverable one, i.e
> there is probability that in the next call to pvrdma_poll_one it will be fine.
> Otherwise it is an endless loop.
We have never run into this issue internally but I don't think we can recover here
in the driver. The only way to recover would be to destroy and recreate the CQ
which we shouldn't do since it could be used by multiple QPs.
We don't have a way yet to recover in the device. Once we add that this check
should go away.
The reason I returned an error value from poll_cq in v3 was to break the possible
loop so that it might give clients a chance to recover. But since poll_cq is not expected
to fail I just log the device error here. I can revert to that version if you want to break
the possible loop.
^ permalink raw reply
* Re: [PATCH net-next 1/7] lwt: Add net to build_state argument
From: kbuild test robot @ 2016-09-14 23:56 UTC (permalink / raw)
To: Tom Herbert; +Cc: kbuild-all, davem, netdev, tgraf, roopa, kernel-team
In-Reply-To: <1473895376-347096-2-git-send-email-tom@herbertland.com>
[-- Attachment #1: Type: text/plain, Size: 17365 bytes --]
Hi Tom,
[auto build test ERROR on net-next/master]
url: https://github.com/0day-ci/linux/commits/Tom-Herbert/net-ILA-resolver-and-generic-resolver-backend/20160915-073357
config: x86_64-randconfig-x013-201637 (attached as .config)
compiler: gcc-6 (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All error/warnings (new ones prefixed by >>):
net/ipv4/fib_semantics.c: In function 'fib_get_nhs':
>> net/ipv4/fib_semantics.c:514:32: error: passing argument 1 of 'lwtunnel_build_state' from incompatible pointer type [-Werror=incompatible-pointer-types]
ret = lwtunnel_build_state(net, dev,
^~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: expected 'struct net_device *' but argument is of type 'struct net *'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
>> net/ipv4/fib_semantics.c:514:37: warning: passing argument 2 of 'lwtunnel_build_state' makes integer from pointer without a cast [-Wint-conversion]
ret = lwtunnel_build_state(net, dev,
^~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: expected 'u16 {aka short unsigned int}' but argument is of type 'struct net_device *'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
>> net/ipv4/fib_semantics.c:515:11: warning: passing argument 3 of 'lwtunnel_build_state' makes pointer from integer without a cast [-Wint-conversion]
nla_get_u16(
^~~~~~~~~~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: expected 'struct nlattr *' but argument is of type 'u16 {aka short unsigned int}'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
net/ipv4/fib_semantics.c:517:11: warning: passing argument 4 of 'lwtunnel_build_state' makes integer from pointer without a cast [-Wint-conversion]
nla, AF_INET, cfg,
^~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: expected 'unsigned int' but argument is of type 'struct nlattr *'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
In file included from net/ipv4/fib_semantics.c:23:0:
>> include/linux/socket.h:163:18: warning: passing argument 5 of 'lwtunnel_build_state' makes pointer from integer without a cast [-Wint-conversion]
#define AF_INET 2 /* Internet IP Protocol */
^
>> net/ipv4/fib_semantics.c:517:17: note: in expansion of macro 'AF_INET'
nla, AF_INET, cfg,
^~~~~~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: expected 'const void *' but argument is of type 'int'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
net/ipv4/fib_semantics.c:517:26: error: passing argument 6 of 'lwtunnel_build_state' from incompatible pointer type [-Werror=incompatible-pointer-types]
nla, AF_INET, cfg,
^~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: expected 'struct lwtunnel_state **' but argument is of type 'struct fib_config *'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
>> net/ipv4/fib_semantics.c:514:11: error: too many arguments to function 'lwtunnel_build_state'
ret = lwtunnel_build_state(net, dev,
^~~~~~~~~~~~~~~~~~~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: declared here
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
net/ipv4/fib_semantics.c: In function 'fib_encap_match':
net/ipv4/fib_semantics.c:614:29: error: passing argument 1 of 'lwtunnel_build_state' from incompatible pointer type [-Werror=incompatible-pointer-types]
ret = lwtunnel_build_state(net, dev, encap_type, encap,
^~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: expected 'struct net_device *' but argument is of type 'struct net *'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
net/ipv4/fib_semantics.c:614:34: warning: passing argument 2 of 'lwtunnel_build_state' makes integer from pointer without a cast [-Wint-conversion]
ret = lwtunnel_build_state(net, dev, encap_type, encap,
^~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: expected 'u16 {aka short unsigned int}' but argument is of type 'struct net_device *'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
net/ipv4/fib_semantics.c:614:39: warning: passing argument 3 of 'lwtunnel_build_state' makes pointer from integer without a cast [-Wint-conversion]
ret = lwtunnel_build_state(net, dev, encap_type, encap,
^~~~~~~~~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: expected 'struct nlattr *' but argument is of type 'u16 {aka short unsigned int}'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
net/ipv4/fib_semantics.c:614:51: warning: passing argument 4 of 'lwtunnel_build_state' makes integer from pointer without a cast [-Wint-conversion]
ret = lwtunnel_build_state(net, dev, encap_type, encap,
^~~~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: expected 'unsigned int' but argument is of type 'struct nlattr *'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
In file included from net/ipv4/fib_semantics.c:23:0:
>> include/linux/socket.h:163:18: warning: passing argument 5 of 'lwtunnel_build_state' makes pointer from integer without a cast [-Wint-conversion]
#define AF_INET 2 /* Internet IP Protocol */
^
net/ipv4/fib_semantics.c:615:8: note: in expansion of macro 'AF_INET'
AF_INET, cfg, &lwtstate);
^~~~~~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: expected 'const void *' but argument is of type 'int'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
net/ipv4/fib_semantics.c:615:17: error: passing argument 6 of 'lwtunnel_build_state' from incompatible pointer type [-Werror=incompatible-pointer-types]
AF_INET, cfg, &lwtstate);
^~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: expected 'struct lwtunnel_state **' but argument is of type 'const struct fib_config *'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
net/ipv4/fib_semantics.c:614:8: error: too many arguments to function 'lwtunnel_build_state'
ret = lwtunnel_build_state(net, dev, encap_type, encap,
^~~~~~~~~~~~~~~~~~~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: declared here
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
net/ipv4/fib_semantics.c: In function 'fib_create_info':
net/ipv4/fib_semantics.c:1102:31: error: passing argument 1 of 'lwtunnel_build_state' from incompatible pointer type [-Werror=incompatible-pointer-types]
err = lwtunnel_build_state(net, dev, cfg->fc_encap_type,
^~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: expected 'struct net_device *' but argument is of type 'struct net *'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
net/ipv4/fib_semantics.c:1102:36: warning: passing argument 2 of 'lwtunnel_build_state' makes integer from pointer without a cast [-Wint-conversion]
err = lwtunnel_build_state(net, dev, cfg->fc_encap_type,
^~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: expected 'u16 {aka short unsigned int}' but argument is of type 'struct net_device *'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
net/ipv4/fib_semantics.c:1102:41: warning: passing argument 3 of 'lwtunnel_build_state' makes pointer from integer without a cast [-Wint-conversion]
err = lwtunnel_build_state(net, dev, cfg->fc_encap_type,
^~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: expected 'struct nlattr *' but argument is of type 'u16 {aka short unsigned int}'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
net/ipv4/fib_semantics.c:1103:10: warning: passing argument 4 of 'lwtunnel_build_state' makes integer from pointer without a cast [-Wint-conversion]
cfg->fc_encap, AF_INET, cfg,
^~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: expected 'unsigned int' but argument is of type 'struct nlattr *'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
In file included from net/ipv4/fib_semantics.c:23:0:
>> include/linux/socket.h:163:18: warning: passing argument 5 of 'lwtunnel_build_state' makes pointer from integer without a cast [-Wint-conversion]
#define AF_INET 2 /* Internet IP Protocol */
^
net/ipv4/fib_semantics.c:1103:25: note: in expansion of macro 'AF_INET'
cfg->fc_encap, AF_INET, cfg,
^~~~~~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: expected 'const void *' but argument is of type 'int'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
net/ipv4/fib_semantics.c:1103:34: error: passing argument 6 of 'lwtunnel_build_state' from incompatible pointer type [-Werror=incompatible-pointer-types]
cfg->fc_encap, AF_INET, cfg,
^~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: expected 'struct lwtunnel_state **' but argument is of type 'struct fib_config *'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
net/ipv4/fib_semantics.c:1102:10: error: too many arguments to function 'lwtunnel_build_state'
err = lwtunnel_build_state(net, dev, cfg->fc_encap_type,
^~~~~~~~~~~~~~~~~~~~
In file included from net/ipv4/fib_semantics.c:45:0:
include/net/lwtunnel.h:172:19: note: declared here
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
--
net/ipv6/route.c: In function 'ip6_route_info_create':
>> net/ipv6/route.c:1887:30: error: passing argument 1 of 'lwtunnel_build_state' from incompatible pointer type [-Werror=incompatible-pointer-types]
err = lwtunnel_build_state(net, dev, cfg->fc_encap_type,
^~~
In file included from include/net/ip_tunnels.h:17:0,
from include/net/dst_metadata.h:5,
from net/ipv6/route.c:57:
include/net/lwtunnel.h:172:19: note: expected 'struct net_device *' but argument is of type 'struct net *'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
>> net/ipv6/route.c:1887:35: warning: passing argument 2 of 'lwtunnel_build_state' makes integer from pointer without a cast [-Wint-conversion]
err = lwtunnel_build_state(net, dev, cfg->fc_encap_type,
^~~
In file included from include/net/ip_tunnels.h:17:0,
from include/net/dst_metadata.h:5,
from net/ipv6/route.c:57:
include/net/lwtunnel.h:172:19: note: expected 'u16 {aka short unsigned int}' but argument is of type 'struct net_device *'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
>> net/ipv6/route.c:1887:40: warning: passing argument 3 of 'lwtunnel_build_state' makes pointer from integer without a cast [-Wint-conversion]
err = lwtunnel_build_state(net, dev, cfg->fc_encap_type,
^~~
In file included from include/net/ip_tunnels.h:17:0,
from include/net/dst_metadata.h:5,
from net/ipv6/route.c:57:
include/net/lwtunnel.h:172:19: note: expected 'struct nlattr *' but argument is of type 'u16 {aka short unsigned int}'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
net/ipv6/route.c:1888:9: warning: passing argument 4 of 'lwtunnel_build_state' makes integer from pointer without a cast [-Wint-conversion]
cfg->fc_encap, AF_INET6, cfg,
^~~
In file included from include/net/ip_tunnels.h:17:0,
from include/net/dst_metadata.h:5,
from net/ipv6/route.c:57:
include/net/lwtunnel.h:172:19: note: expected 'unsigned int' but argument is of type 'struct nlattr *'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
In file included from net/ipv6/route.c:34:0:
include/linux/socket.h:171:18: warning: passing argument 5 of 'lwtunnel_build_state' makes pointer from integer without a cast [-Wint-conversion]
#define AF_INET6 10 /* IP version 6 */
^
>> net/ipv6/route.c:1888:24: note: in expansion of macro 'AF_INET6'
cfg->fc_encap, AF_INET6, cfg,
^~~~~~~~
In file included from include/net/ip_tunnels.h:17:0,
from include/net/dst_metadata.h:5,
from net/ipv6/route.c:57:
include/net/lwtunnel.h:172:19: note: expected 'const void *' but argument is of type 'int'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
net/ipv6/route.c:1888:34: error: passing argument 6 of 'lwtunnel_build_state' from incompatible pointer type [-Werror=incompatible-pointer-types]
cfg->fc_encap, AF_INET6, cfg,
^~~
In file included from include/net/ip_tunnels.h:17:0,
from include/net/dst_metadata.h:5,
from net/ipv6/route.c:57:
include/net/lwtunnel.h:172:19: note: expected 'struct lwtunnel_state **' but argument is of type 'struct fib6_config *'
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
>> net/ipv6/route.c:1887:9: error: too many arguments to function 'lwtunnel_build_state'
err = lwtunnel_build_state(net, dev, cfg->fc_encap_type,
^~~~~~~~~~~~~~~~~~~~
In file included from include/net/ip_tunnels.h:17:0,
from include/net/dst_metadata.h:5,
from net/ipv6/route.c:57:
include/net/lwtunnel.h:172:19: note: declared here
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
^~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
vim +/lwtunnel_build_state +514 net/ipv4/fib_semantics.c
508 nla_entype = nla_find(attrs, attrlen,
509 RTA_ENCAP_TYPE);
510 if (!nla_entype)
511 goto err_inval;
512 if (cfg->fc_oif)
513 dev = __dev_get_by_index(net, cfg->fc_oif);
> 514 ret = lwtunnel_build_state(net, dev,
> 515 nla_get_u16(
516 nla_entype),
> 517 nla, AF_INET, cfg,
518 &lwtstate);
519 if (ret)
520 goto errout;
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 29178 bytes --]
^ permalink raw reply
* RE: [Intel-wired-lan] [net-next PATCH v3 1/3] e1000: track BQL bytes regardless of skb or not
From: Brown, Aaron F @ 2016-09-14 23:57 UTC (permalink / raw)
To: John Fastabend, bblanco@plumgrid.com,
alexei.starovoitov@gmail.com, Kirsher, Jeffrey T,
brouer@redhat.com, davem@davemloft.net
Cc: xiyou.wangcong@gmail.com, intel-wired-lan@lists.osuosl.org,
u9012063@gmail.com, netdev@vger.kernel.org
In-Reply-To: <20160912221327.5610.74333.stgit@john-Precision-Tower-5810>
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces@lists.osuosl.org] On
> Behalf Of John Fastabend
> Sent: Monday, September 12, 2016 3:13 PM
> To: bblanco@plumgrid.com; john.fastabend@gmail.com;
> alexei.starovoitov@gmail.com; Kirsher, Jeffrey T
> <jeffrey.t.kirsher@intel.com>; brouer@redhat.com; davem@davemloft.net
> Cc: xiyou.wangcong@gmail.com; intel-wired-lan@lists.osuosl.org;
> u9012063@gmail.com; netdev@vger.kernel.org
> Subject: [Intel-wired-lan] [net-next PATCH v3 1/3] e1000: track BQL bytes
> regardless of skb or not
>
> The BQL API does not reference the sk_buff nor does the driver need to
> reference the sk_buff to calculate the length of a transmitted frame.
> This patch removes an sk_buff reference from the xmit irq path and
> also allows packets sent from XDP to use BQL.
>
> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
> ---
> drivers/net/ethernet/intel/e1000/e1000_main.c | 7 ++-----
> 1 file changed, 2 insertions(+), 5 deletions(-)
This patch is causing all my e1000 adapters to fail a simple ftp session with really slow response (hashing on) followed by adapter resets. I have seen this on 4 different e1000 nics now, an 82543GC, 82544GC, 82546EB and an 82545GM. On a few occasions I get a splat captured to dmesg. Here is an example:
--------------------------------
------------[ cut here ]------------
WARNING: CPU: 1 PID: 0 at net/sched/sch_generic.c:316 dev_watchdog+0x1c2/0x1d0
NETDEV WATCHDOG: eth1 (e1000): transmit queue 0 timed out
Modules linked in: e1000 e100 nfsd lockd grace nfs_acl auth_rpcgss sunrpc autofs
4 ipv6 crc_ccitt p4_clockmod dm_mirror dm_region_hash dm_log uinput sg serio_raw
dcdbas mii i2c_piix4 i2c_core cfi_probe gen_probe cfi_util scb2_flash dm_mod(E)
ext4(E) mbcache(E) jbd2(E) sd_mod(E) sr_mod(E) cdrom(E) aacraid(E) pata_acpi(E)
ata_generic(E) pata_serverworks(E) [last unloaded: e1000]
CPU: 1 PID: 0 Comm: swapper/1 Tainted: G E 4.8.0-rc6_next-queue_dev
-queue_b0b5ade #8
Hardware name: Dell Computer Corporation PowerEdge 2650 /0D5995, BIO
S A21 10/05/2006
00000000 c06724fb c0b6038a c0b6038a 0000013c c04596d5 c0b647ac f3d2fed0
00000000 c0b6038a 0000013c c08bff52 c08bff52 00000009 f2922000 00000000
f318cf00 0001e788 c045979b 00000009 00000000 f3d2feb8 c0b647ac f3d2fed0
Call Trace:
[<c06724fb>] ? dump_stack+0x47/0x6c
[<c04596d5>] ? __warn+0x105/0x120
[<c08bff52>] ? dev_watchdog+0x1c2/0x1d0
[<c08bff52>] ? dev_watchdog+0x1c2/0x1d0
[<c045979b>] ? warn_slowpath_fmt+0x3b/0x40
[<c08bff52>] ? dev_watchdog+0x1c2/0x1d0
[<c04bb71b>] ? call_timer_fn+0x3b/0x140
[<c08bfd90>] ? dev_trans_start+0x60/0x60
[<c04bc1ab>] ? expire_timers+0x9b/0x110
[<c04bc471>] ? run_timer_softirq+0xd1/0x260
[<c089a1e0>] ? net_tx_action+0xe0/0x1a0
[<c04b8597>] ? rcu_process_callbacks+0x47/0xe0
[<c045e518>] ? __do_softirq+0xc8/0x280
[<c045e450>] ? irq_exit+0x90/0x90
[<c041dbd2>] ? do_softirq_own_stack+0x22/0x30
<IRQ> [<c045e445>] ? irq_exit+0x85/0x90
[<c0440f80>] ? smp_apic_timer_interrupt+0x30/0x40
[<c095f44d>] ? apic_timer_interrupt+0x2d/0x34
[<c04251cc>] ? default_idle+0x1c/0xd0
[<c04ce222>] ? __tick_nohz_idle_enter+0x92/0x140
[<c0424cc6>] ? arch_cpu_idle+0x6/0x10
[<c0495ebd>] ? cpuidle_idle_call+0x7d/0xe0
[<c0496075>] ? cpu_idle_loop+0x155/0x210
[<c04404a5>] ? start_secondary+0xb5/0xe0
---[ end trace fa448b49f7848a42 ]---
e1000 0000:02:06.0 eth1: Reset adapter
e1000: eth1 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX/TX
e1000 0000:02:06.0 eth1: Reset adapter
e1000: eth1 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX/TX
e1000 0000:02:06.0 eth1: Reset adapter
e1000: eth1 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX/TX
e1000 0000:02:06.0 eth1: Reset adapter
e1000: eth1 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX/TX
e1000 0000:02:06.0 eth1: Reset adapter
e1000: eth1 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX/TX
e1000 0000:02:06.0 eth1: Reset adapter
e1000: eth1 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX/TX
e1000 0000:02:06.0 eth1: Reset adapter
e1000: eth1 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX/TX
^ permalink raw reply
* RE: [Intel-wired-lan] [net-next PATCH v3 2/3] e1000: add initial XDP support
From: Brown, Aaron F @ 2016-09-14 23:42 UTC (permalink / raw)
To: Rustad, Mark D, Alexei Starovoitov
Cc: Eric Dumazet, Tom Herbert, Brenden Blanco,
Linux Kernel Network Developers, intel-wired-lan, William Tu,
Jesper Dangaard Brouer, Cong Wang, David S. Miller
In-Reply-To: <151DF165-61A2-428A-BD24-04E7704F9724@intel.com>
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces@lists.osuosl.org] On
> Behalf Of Rustad, Mark D
> Sent: Tuesday, September 13, 2016 3:41 PM
> To: Alexei Starovoitov <alexei.starovoitov@gmail.com>
> Cc: Eric Dumazet <eric.dumazet@gmail.com>; Tom Herbert
> <tom@herbertland.com>; Brenden Blanco <bblanco@plumgrid.com>; Linux
> Kernel Network Developers <netdev@vger.kernel.org>; intel-wired-lan <intel-
> wired-lan@lists.osuosl.org>; William Tu <u9012063@gmail.com>; Jesper
> Dangaard Brouer <brouer@redhat.com>; Cong Wang
> <xiyou.wangcong@gmail.com>; David S. Miller <davem@davemloft.net>
> Subject: Re: [Intel-wired-lan] [net-next PATCH v3 2/3] e1000: add initial XDP
> support
>
> Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
>
> > On Tue, Sep 13, 2016 at 07:14:27PM +0000, Rustad, Mark D wrote:
> >> Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
> >>
> >>> On Tue, Sep 13, 2016 at 06:28:03PM +0000, Rustad, Mark D wrote:
> >>>> Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
> >>>>
> >>>>> I've looked through qemu and it appears only emulate e1k and tg3.
> >>>>> The latter is still used in the field, so the risk of touching
> >>>>> it is higher.
> >>>>
> >>>> I have no idea what makes you think that e1k is *not* "used in the
> >>>> field".
I personally use a number of physical e1000 parts in my lab. Primarily for an out of band control adapter, as it almost never changes so tends to be very stable, and it is rare that I have to test it so I'm not fighting with a control adapter that I am also testing the driver on.
> >>>> I grant you it probably is used more virtualized than not these days,
> >>>> but it
> >>>> certainly exists and is used. You can still buy them new at Newegg for
> >>>> goodness sakes!
> >>>
> >>> the point that it's only used virtualized, since PCI (not PCIE) have
> >>> been long dead.
Maybe for new server installations. But modern motherboards often still have PCI, university / lab environments are slow to upgrade specialty test equipment that uses PCI and home users often don't want to get rid of their expensive high quality sound card, video capture card (or whatever.) Plain old PCI is still in use.
> >>
> >> My point is precisely the opposite. It is a real device, it exists in real
> >> systems and it is used in those systems. I worked on embedded systems
> that
> >> ran Linux and used e1000 devices. I am sure they are still out there
> >> because
> >> customers are still paying for support of those systems.
> >>
> >> Yes, PCI(-X) is absent from any current hardware and has been for some
> >> years
> >> now, but there is an installed base that continues. What part of that
> >> installed base updates software? I don't know, but I would not just
> assume
> >> that it is 0. I know that I updated the kernel on those embedded systems
> >> that I worked on when I was supporting them. Never at the bleeding edge,
> >> but
> >> generally hopping from one LTS kernel to another as needed.
> >
> > I suspect modern linux won't boot on such old pci only systems for other
> > reasons not related to networking, since no one really cares to test
> > kernels there.
>
> Actually it does boot, because although the motherboard was PCIe, the slots
> and the adapters in them were PCI-X. So the core architecture was not so
> stale.
>
> > So I think we mostly agree. There is chance that this xdp e1k code will
> > find a way to that old system. What are the chances those users will
> > be using xdp there? I think pretty close to zero.
>
> For sure they wouldn't be using XDP, but they could suffer regressions in a
> changed driver that might find its way there. That is the risk.
>
> > The pci-e nics integrated into motherboards that pretend to be tg3
> > (though they're not at all build by broadcom) are significantly more
> > common.
> > That's why I picked e1k instead of tg3.
>
> That may be true (I really don't know anything about tg3 so I certainly
> can't dispute it), so the risk could be smaller with e1k, but there is
> still a regression risk for real existing hardware. That is my concern.
And one of the patches in supporting this seems to have done just that. I'll reply to the patch itself with details.
>
> > Also note how this patch is not touching anything in the main e1k path
> > (because I don't have a hw to test and I suspect Intel's driver team
> > doesn't have it either)
Your suspicion is incorrect. My lab has multiple boxes out on benches and at least one cabinet 3/4 full of ancient hardware, including a decent variety of e1000 cards (and even a number of e100 ones.) I also keep a handful of test systems in my regression rack devoted to e1000, though those have dwindled (old hardware eventually dies) and is currently in need of a bit of work, which this patch set has encouraged me to get on to.
> > to make sure there is no breakage on those
> > old systems. I created separate e1000_xmit_raw_frame() routine
> > instead of adding flags into e1000_xmit_frame() for the same reasons:
> > to make sure there is no breakage.
> > Same reasoning for not doing an union of page/skb as Alexander
> suggested.
> > I wanted minimal change to e1k that allows development xdp programs in
> kvm
> > without affecting e1k main path. If you see the actual bug in the patch,
> > please point out the line.
>
> I can't say that I can, because I am not familiar with the internals of
> e1k. When I was using it, I never had cause to even look at the driver
> because it just worked. My attentions then were properly elsewhere.
>
> My concern is with messing with a driver that probably no one has an active
> testbed routinely running regression tests.
>
> Maybe a new ID should be assigned and the driver forked for this purpose.
> At least then only the virtualization case would have to be tested. Of
> course the hosts would have to offer that ID, but if this is just for
> testing that should be ok, or at least possible.
>
> If someone with more internal knowledge of this driver has enough
> confidence to bless such patches, that might be fine, but it is a fallacy
> to think that e1k is *only* a virtualization driver today. Not yet anyway.
> Maybe around 2020.
>
> That said, I can see that you have tried to keep the original code path
> pretty much intact. I would note that you introduced rcu calls into the
> !bpf path that would never have been done before. While that should be ok,
> I would really like to see it tested, at least for the !bpf case, on real
> hardware to be sure. I really can't comment on the workaround issue
> brought
> up by Eric, because I just don't know about them. At least that risk seems
> to only be in the bpf case.
>
> --
> Mark Rustad, Networking Division, Intel Corporation
^ permalink raw reply
* [PATCH v2] net: VRF: Pass original iif to ip_route_input()
From: Mark Tomlinson @ 2016-09-14 23:40 UTC (permalink / raw)
To: dsa, netdev; +Cc: Mark Tomlinson
In-Reply-To: <20160912014553.20927-1-mark.tomlinson@alliedtelesis.co.nz>
The function ip_rcv_finish() calls l3mdev_ip_rcv(). On any VRF except
the global VRF, this replaces skb->dev with the VRF master interface.
When calling ip_route_input_noref() from here, the checks for forwarding
look at this master device instead of the initial ingress interface.
This will allow packets to be routed which normally would be dropped.
For example, an interface that is not assigned an IP address should
drop packets, but because the checking is against the master device, the
packet will be forwarded.
The fix here is to still call l3mdev_ip_rcv(), but remember the initial
net_device. This is passed to the other functions within ip_rcv_finish,
so they still see the original interface.
Signed-off-by: Mark Tomlinson <mark.tomlinson@alliedtelesis.co.nz>
Acked-by: David Ahern <dsa@cumulusnetworks.com>
---
net/ipv4/ip_input.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 4b351af..d6feabb 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -312,6 +312,7 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
{
const struct iphdr *iph = ip_hdr(skb);
struct rtable *rt;
+ struct net_device *dev = skb->dev;
/* if ingress device is enslaved to an L3 master device pass the
* skb to its handler for processing
@@ -341,7 +342,7 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
*/
if (!skb_valid_dst(skb)) {
int err = ip_route_input_noref(skb, iph->daddr, iph->saddr,
- iph->tos, skb->dev);
+ iph->tos, dev);
if (unlikely(err)) {
if (err == -EXDEV)
__NET_INC_STATS(net, LINUX_MIB_IPRPFILTER);
@@ -370,7 +371,7 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
__IP_UPD_PO_STATS(net, IPSTATS_MIB_INBCAST, skb->len);
} else if (skb->pkt_type == PACKET_BROADCAST ||
skb->pkt_type == PACKET_MULTICAST) {
- struct in_device *in_dev = __in_dev_get_rcu(skb->dev);
+ struct in_device *in_dev = __in_dev_get_rcu(dev);
/* RFC 1122 3.3.6:
*
--
2.9.3
^ permalink raw reply related
* Re: [RFC v3 03/22] bpf,landlock: Add a new arraymap type to deal with (Landlock) handles
From: Alexei Starovoitov @ 2016-09-14 23:28 UTC (permalink / raw)
To: Mickaël Salaün
Cc: linux-kernel, Alexei Starovoitov, Andy Lutomirski, Arnd Bergmann,
Casey Schaufler, Daniel Borkmann, Daniel Mack, David Drysdale,
David S . Miller, Elena Reshetova, Eric W . Biederman,
James Morris, Kees Cook, Paul Moore, Sargun Dhillon,
Serge E . Hallyn, Tejun Heo, Will Drewry, kernel-hardening,
linux-api, linux-security-module
In-Reply-To: <57D9DBC9.2010605@digikod.net>
On Thu, Sep 15, 2016 at 01:22:49AM +0200, Mickaël Salaün wrote:
>
> On 14/09/2016 20:51, Alexei Starovoitov wrote:
> > On Wed, Sep 14, 2016 at 09:23:56AM +0200, Mickaël Salaün wrote:
> >> This new arraymap looks like a set and brings new properties:
> >> * strong typing of entries: the eBPF functions get the array type of
> >> elements instead of CONST_PTR_TO_MAP (e.g.
> >> CONST_PTR_TO_LANDLOCK_HANDLE_FS);
> >> * force sequential filling (i.e. replace or append-only update), which
> >> allow quick browsing of all entries.
> >>
> >> This strong typing is useful to statically check if the content of a map
> >> can be passed to an eBPF function. For example, Landlock use it to store
> >> and manage kernel objects (e.g. struct file) instead of dealing with
> >> userland raw data. This improve efficiency and ensure that an eBPF
> >> program can only call functions with the right high-level arguments.
> >>
> >> The enum bpf_map_handle_type list low-level types (e.g.
> >> BPF_MAP_HANDLE_TYPE_LANDLOCK_FS_FD) which are identified when
> >> updating a map entry (handle). This handle types are used to infer a
> >> high-level arraymap type which are listed in enum bpf_map_array_type
> >> (e.g. BPF_MAP_ARRAY_TYPE_LANDLOCK_FS).
> >>
> >> For now, this new arraymap is only used by Landlock LSM (cf. next
> >> commits) but it could be useful for other needs.
> >>
> >> Changes since v2:
> >> * add a RLIMIT_NOFILE-based limit to the maximum number of arraymap
> >> handle entries (suggested by Andy Lutomirski)
> >> * remove useless checks
> >>
> >> Changes since v1:
> >> * arraymap of handles replace custom checker groups
> >> * simpler userland API
> >>
> >> Signed-off-by: Mickaël Salaün <mic@digikod.net>
> >> Cc: Alexei Starovoitov <ast@kernel.org>
> >> Cc: Andy Lutomirski <luto@amacapital.net>
> >> Cc: Daniel Borkmann <daniel@iogearbox.net>
> >> Cc: David S. Miller <davem@davemloft.net>
> >> Cc: Kees Cook <keescook@chromium.org>
> >> Link: https://lkml.kernel.org/r/CALCETrWwTiz3kZTkEgOW24-DvhQq6LftwEXh77FD2G5o71yD7g@mail.gmail.com
> >> ---
> >> include/linux/bpf.h | 14 ++++
> >> include/uapi/linux/bpf.h | 18 +++++
> >> kernel/bpf/arraymap.c | 203 +++++++++++++++++++++++++++++++++++++++++++++++
> >> kernel/bpf/verifier.c | 12 ++-
> >> 4 files changed, 246 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> >> index fa9a988400d9..eae4ce4542c1 100644
> >> --- a/include/linux/bpf.h
> >> +++ b/include/linux/bpf.h
> >> @@ -13,6 +13,10 @@
> >> #include <linux/percpu.h>
> >> #include <linux/err.h>
> >>
> >> +#ifdef CONFIG_SECURITY_LANDLOCK
> >> +#include <linux/fs.h> /* struct file */
> >> +#endif /* CONFIG_SECURITY_LANDLOCK */
> >> +
> >> struct perf_event;
> >> struct bpf_map;
> >>
> >> @@ -38,6 +42,7 @@ struct bpf_map_ops {
> >> struct bpf_map {
> >> atomic_t refcnt;
> >> enum bpf_map_type map_type;
> >> + enum bpf_map_array_type map_array_type;
> >> u32 key_size;
> >> u32 value_size;
> >> u32 max_entries;
> >> @@ -187,6 +192,9 @@ struct bpf_array {
> >> */
> >> enum bpf_prog_type owner_prog_type;
> >> bool owner_jited;
> >> +#ifdef CONFIG_SECURITY_LANDLOCK
> >> + u32 n_entries; /* number of entries in a handle array */
> >> +#endif /* CONFIG_SECURITY_LANDLOCK */
> >> union {
> >> char value[0] __aligned(8);
> >> void *ptrs[0] __aligned(8);
> >> @@ -194,6 +202,12 @@ struct bpf_array {
> >> };
> >> };
> >>
> >> +#ifdef CONFIG_SECURITY_LANDLOCK
> >> +struct map_landlock_handle {
> >> + u32 type; /* enum bpf_map_handle_type */
> >> +};
> >> +#endif /* CONFIG_SECURITY_LANDLOCK */
> >> +
> >> #define MAX_TAIL_CALL_CNT 32
> >>
> >> struct bpf_event_entry {
> >> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> >> index 7cd36166f9b7..b68de57f7ab8 100644
> >> --- a/include/uapi/linux/bpf.h
> >> +++ b/include/uapi/linux/bpf.h
> >> @@ -87,6 +87,15 @@ enum bpf_map_type {
> >> BPF_MAP_TYPE_PERCPU_ARRAY,
> >> BPF_MAP_TYPE_STACK_TRACE,P_TYPE_CGROUP_ARRAY
> >> BPF_MAP_TYPE_CGROUP_ARRAY,
> >> + BPF_MAP_TYPE_LANDLOCK_ARRAY,
> >> +};
> >> +
> >> +enum bpf_map_array_type {
> >> + BPF_MAP_ARRAY_TYPE_UNSPEC,
> >> +};
> >> +
> >> +enum bpf_map_handle_type {
> >> + BPF_MAP_HANDLE_TYPE_UNSPEC,
> >> };
> >
> > missing something. why it has to be special to have it's own
> > fd array implementation?
> > Please take a look how BPF_MAP_TYPE_PERF_EVENT_ARRAY,
> > BPF_MAP_TYPE_CGROUP_ARRAY and BPF_MAP_TYPE_PROG_ARRAY are done.
> > The all store objects into array map that user space passes via FD.
> > I think the same model should apply here.
>
> The idea is to have multiple way for userland to describe a resource
> (e.g. an open file descriptor, a path or a glob pattern). The kernel
> representation could then be a "struct path *" or dedicated types (e.g.
> custom glob).
hmm. I think user space api should only deal with FD. Everything
else is user space job to encapsulate/hide.
> Another interesting point (that could replace
> check_map_func_compatibility()) is that BPF_MAP_TYPE_LANDLOCK_ARRAY
> translate to dedicated (abstract) types (instead of CONST_PTR_TO_MAP)
> thanks to bpf_reg_type_from_map(). This is useful to abstract userland
> (map) interface with kernel object(s) dealing with that type.
I probably missing something. If user space interface is FD,
to the kernel they're different object types. Nothing else.
> A third point is that BPF_MAP_TYPE_LANDLOCK_ARRAY is a kind of set. It
> is optimized to quickly walk through all the elements in a sequential way.
why set is any faster to walk vs array?
^ permalink raw reply
* [PATCH net-next 7/7] ila: Resolver mechanism
From: Tom Herbert @ 2016-09-14 23:22 UTC (permalink / raw)
To: davem, netdev; +Cc: tgraf, roopa, kernel-team
In-Reply-To: <1473895376-347096-1-git-send-email-tom@herbertland.com>
Implement an ILA resolver. This uses LWT to implement the hook to a
userspace resolver and tracks pending unresolved address using the
backend net resolver.
The idea is that the kernel sets an ILA resolver route to the
SIR prefix, something like:
ip route add 3333::/64 encap ila-resolve \
via 2401:db00:20:911a::27:0 dev eth0
When a packet hits the route the address is looked up in a resolver
table. If the entry is created (no entry with the address already
exists) then an rtnl message is generated with group
RTNLGRP_ILA_NOTIFY and type RTM_ADDR_RESOLVE. A userspace
daemon can listen for such messages and perform an ILA resolution
protocol to determine the ILA mapping. If the mapping is resolved
then a /128 ila encap router is set so that host can perform
ILA translation and send directly to destination.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
include/uapi/linux/ila.h | 9 ++
include/uapi/linux/lwtunnel.h | 1 +
include/uapi/linux/rtnetlink.h | 8 +-
net/ipv6/Kconfig | 1 +
net/ipv6/ila/Makefile | 2 +-
net/ipv6/ila/ila.h | 16 +++
net/ipv6/ila/ila_common.c | 7 ++
net/ipv6/ila/ila_lwt.c | 9 ++
net/ipv6/ila/ila_resolver.c | 246 +++++++++++++++++++++++++++++++++++++++++
net/ipv6/ila/ila_xlat.c | 15 ++-
10 files changed, 304 insertions(+), 10 deletions(-)
create mode 100644 net/ipv6/ila/ila_resolver.c
diff --git a/include/uapi/linux/ila.h b/include/uapi/linux/ila.h
index 948c0a9..f186f8b 100644
--- a/include/uapi/linux/ila.h
+++ b/include/uapi/linux/ila.h
@@ -42,4 +42,13 @@ enum {
ILA_CSUM_NO_ACTION,
};
+enum {
+ ILA_NOTIFY_ATTR_UNSPEC,
+ ILA_NOTIFY_ATTR_TIMEOUT, /* u32 */
+
+ __ILA_NOTIFY_ATTR_MAX,
+};
+
+#define ILA_NOTIFY_ATTR_MAX (__ILA_NOTIFY_ATTR_MAX - 1)
+
#endif /* _UAPI_LINUX_ILA_H */
diff --git a/include/uapi/linux/lwtunnel.h b/include/uapi/linux/lwtunnel.h
index a478fe8..d880e49 100644
--- a/include/uapi/linux/lwtunnel.h
+++ b/include/uapi/linux/lwtunnel.h
@@ -9,6 +9,7 @@ enum lwtunnel_encap_types {
LWTUNNEL_ENCAP_IP,
LWTUNNEL_ENCAP_ILA,
LWTUNNEL_ENCAP_IP6,
+ LWTUNNEL_ENCAP_ILA_NOTIFY,
__LWTUNNEL_ENCAP_MAX,
};
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index 262f037..a775464 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -12,7 +12,8 @@
*/
#define RTNL_FAMILY_IPMR 128
#define RTNL_FAMILY_IP6MR 129
-#define RTNL_FAMILY_MAX 129
+#define RTNL_FAMILY_ILA 130
+#define RTNL_FAMILY_MAX 130
/****
* Routing/neighbour discovery messages.
@@ -144,6 +145,9 @@ enum {
RTM_GETSTATS = 94,
#define RTM_GETSTATS RTM_GETSTATS
+ RTM_ADDR_RESOLVE = 95,
+#define RTM_ADDR_RESOLVE RTM_ADDR_RESOLVE
+
__RTM_MAX,
#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
};
@@ -656,6 +660,8 @@ enum rtnetlink_groups {
#define RTNLGRP_MPLS_ROUTE RTNLGRP_MPLS_ROUTE
RTNLGRP_NSID,
#define RTNLGRP_NSID RTNLGRP_NSID
+ RTNLGRP_ILA_NOTIFY,
+#define RTNLGRP_ILA_NOTIFY RTNLGRP_ILA_NOTIFY
__RTNLGRP_MAX
};
#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index 2343e4f..cf3ea8e 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -97,6 +97,7 @@ config IPV6_ILA
tristate "IPv6: Identifier Locator Addressing (ILA)"
depends on NETFILTER
select LWTUNNEL
+ select NET_EXT_RESOLVER
---help---
Support for IPv6 Identifier Locator Addressing (ILA).
diff --git a/net/ipv6/ila/Makefile b/net/ipv6/ila/Makefile
index 4b32e59..f2aadc3 100644
--- a/net/ipv6/ila/Makefile
+++ b/net/ipv6/ila/Makefile
@@ -4,4 +4,4 @@
obj-$(CONFIG_IPV6_ILA) += ila.o
-ila-objs := ila_common.o ila_lwt.o ila_xlat.o
+ila-objs := ila_common.o ila_lwt.o ila_xlat.o ila_resolver.o
diff --git a/net/ipv6/ila/ila.h b/net/ipv6/ila/ila.h
index e0170f6..e369611 100644
--- a/net/ipv6/ila/ila.h
+++ b/net/ipv6/ila/ila.h
@@ -15,6 +15,7 @@
#include <linux/ip.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/rhashtable.h>
#include <linux/socket.h>
#include <linux/skbuff.h>
#include <linux/types.h>
@@ -23,6 +24,16 @@
#include <net/protocol.h>
#include <uapi/linux/ila.h>
+extern unsigned int ila_net_id;
+
+struct ila_net {
+ struct rhashtable rhash_table;
+ spinlock_t *locks; /* Bucket locks for entry manipulation */
+ unsigned int locks_mask;
+ bool hooks_registered;
+ struct net_rslv *nrslv;
+};
+
struct ila_locator {
union {
__u8 v8[8];
@@ -114,9 +125,14 @@ void ila_update_ipv6_locator(struct sk_buff *skb, struct ila_params *p,
void ila_init_saved_csum(struct ila_params *p);
+void ila_rslv_resolved(struct ila_net *ilan, struct ila_addr *iaddr);
int ila_lwt_init(void);
void ila_lwt_fini(void);
int ila_xlat_init(void);
void ila_xlat_fini(void);
+int ila_rslv_init(void);
+void ila_rslv_fini(void);
+int ila_init_resolver_net(struct ila_net *ilan);
+void ila_exit_resolver_net(struct ila_net *ilan);
#endif /* __ILA_H */
diff --git a/net/ipv6/ila/ila_common.c b/net/ipv6/ila/ila_common.c
index aba0998..83c7d4a 100644
--- a/net/ipv6/ila/ila_common.c
+++ b/net/ipv6/ila/ila_common.c
@@ -157,7 +157,13 @@ static int __init ila_init(void)
if (ret)
goto fail_xlat;
+ ret = ila_rslv_init();
+ if (ret)
+ goto fail_rslv;
+
return 0;
+fail_rslv:
+ ila_xlat_fini();
fail_xlat:
ila_lwt_fini();
fail_lwt:
@@ -168,6 +174,7 @@ static void __exit ila_fini(void)
{
ila_xlat_fini();
ila_lwt_fini();
+ ila_rslv_fini();
}
module_init(ila_init);
diff --git a/net/ipv6/ila/ila_lwt.c b/net/ipv6/ila/ila_lwt.c
index 30a6920..70d8988 100644
--- a/net/ipv6/ila/ila_lwt.c
+++ b/net/ipv6/ila/ila_lwt.c
@@ -9,6 +9,7 @@
#include <net/ip.h>
#include <net/ip6_fib.h>
#include <net/lwtunnel.h>
+#include <net/netns/generic.h>
#include <net/protocol.h>
#include <uapi/linux/ila.h>
#include "ila.h"
@@ -122,6 +123,14 @@ static int ila_build_state(struct net *net, struct net_device *dev,
*ts = newts;
+ if (cfg6->fc_dst_len >= sizeof(struct ila_addr)) {
+ struct net *net = dev_net(dev);
+ struct ila_net *ilan = net_generic(net, ila_net_id);
+
+ /* Cancel any pending resolution on this address */
+ ila_rslv_resolved(ilan, iaddr);
+ }
+
return 0;
}
diff --git a/net/ipv6/ila/ila_resolver.c b/net/ipv6/ila/ila_resolver.c
new file mode 100644
index 0000000..0b975d6
--- /dev/null
+++ b/net/ipv6/ila/ila_resolver.c
@@ -0,0 +1,246 @@
+#include <linux/errno.h>
+#include <linux/ip.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netlink.h>
+#include <linux/skbuff.h>
+#include <linux/socket.h>
+#include <linux/types.h>
+#include <net/checksum.h>
+#include <net/ip.h>
+#include <net/ip6_fib.h>
+#include <net/lwtunnel.h>
+#include <net/netns/generic.h>
+#include <net/protocol.h>
+#include <net/resolver.h>
+#include <uapi/linux/ila.h>
+#include "ila.h"
+
+struct ila_notify_params {
+ unsigned int timeout;
+};
+
+static inline struct ila_notify_params *ila_notify_params_lwtunnel(
+ struct lwtunnel_state *lwstate)
+{
+ return (struct ila_notify_params *)lwstate->data;
+}
+
+static int ila_fill_notify(struct sk_buff *skb, struct in6_addr *addr,
+ u32 pid, u32 seq, int event, int flags)
+{
+ struct nlmsghdr *nlh;
+ struct rtmsg *rtm;
+
+ nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), flags);
+ if (!nlh)
+ return -EMSGSIZE;
+
+ rtm = nlmsg_data(nlh);
+ rtm->rtm_family = RTNL_FAMILY_ILA;
+ rtm->rtm_dst_len = 128;
+ rtm->rtm_src_len = 0;
+ rtm->rtm_tos = 0;
+ rtm->rtm_table = RT6_TABLE_UNSPEC;
+ rtm->rtm_type = RTN_UNICAST;
+ rtm->rtm_scope = RT_SCOPE_UNIVERSE;
+
+ if (nla_put_in6_addr(skb, RTA_DST, addr)) {
+ nlmsg_cancel(skb, nlh);
+ return -EMSGSIZE;
+ }
+
+ nlmsg_end(skb, nlh);
+ return 0;
+}
+
+static size_t ila_rslv_msgsize(void)
+{
+ size_t len =
+ NLMSG_ALIGN(sizeof(struct rtmsg))
+ + nla_total_size(16) /* RTA_DST */
+ ;
+
+ return len;
+}
+
+void ila_rslv_notify(struct net *net, struct sk_buff *skb)
+{
+ struct ipv6hdr *ip6h = ipv6_hdr(skb);
+ struct sk_buff *nlskb;
+ int err = 0;
+
+ /* Send ILA notification to user */
+ nlskb = nlmsg_new(ila_rslv_msgsize(), GFP_KERNEL);
+ if (!nlskb)
+ goto errout;
+
+ err = ila_fill_notify(nlskb, &ip6h->daddr, 0, 0, RTM_ADDR_RESOLVE,
+ NLM_F_MULTI);
+ if (err < 0) {
+ WARN_ON(err == -EMSGSIZE);
+ kfree_skb(nlskb);
+ goto errout;
+ }
+ rtnl_notify(nlskb, net, 0, RTNLGRP_ILA_NOTIFY, NULL, GFP_ATOMIC);
+ return;
+
+errout:
+ if (err < 0)
+ rtnl_set_sk_err(net, RTNLGRP_ILA_NOTIFY, err);
+}
+
+static int ila_rslv_output(struct net *net, struct sock *sk,
+ struct sk_buff *skb)
+{
+ struct ila_net *ilan = net_generic(net, ila_net_id);
+ struct dst_entry *dst = skb_dst(skb);
+ struct net_rslv_ent *nrent;
+ struct ipv6hdr *ip6h = ipv6_hdr(skb);
+ struct ila_notify_params *p;
+ bool new;
+
+ p = ila_notify_params_lwtunnel(dst->lwtstate);
+
+ /* Don't bother taking rcu lock, we only want to know if the entry
+ * exists or not.
+ */
+ nrent = net_rslv_lookup_and_create(ilan->nrslv, &ip6h->daddr, &new,
+ p->timeout);
+
+ if (nrent && new)
+ ila_rslv_notify(net, skb);
+
+ return dst->lwtstate->orig_output(net, sk, skb);
+}
+
+void ila_rslv_resolved(struct ila_net *ilan, struct ila_addr *iaddr)
+{
+ if (ilan->nrslv)
+ net_rslv_resolved(ilan->nrslv, iaddr);
+}
+
+static int ila_rslv_input(struct sk_buff *skb)
+{
+ struct dst_entry *dst = skb_dst(skb);
+
+ return dst->lwtstate->orig_input(skb);
+}
+
+static const struct nla_policy ila_notify_nl_policy[ILA_NOTIFY_ATTR_MAX + 1] = {
+ [ILA_NOTIFY_ATTR_TIMEOUT] = { .type = NLA_U32, },
+};
+
+static int ila_rslv_build_state(struct net *net, struct net_device *dev,
+ struct nlattr *nla, unsigned int family,
+ const void *cfg, struct lwtunnel_state **ts)
+{
+ struct ila_notify_params *p;
+ struct nlattr *tb[ILA_NOTIFY_ATTR_MAX + 1];
+ struct lwtunnel_state *newts;
+ struct ila_net *ilan = net_generic(net, ila_net_id);
+ size_t encap_len = sizeof(*p);
+ int ret;
+
+ if (unlikely(!ilan->nrslv)) {
+ int err;
+
+ /* Only create net resolver on demand */
+ err = ila_init_resolver_net(ilan);
+ if (err)
+ return err;
+ }
+
+ if (family != AF_INET6)
+ return -EINVAL;
+
+ ret = nla_parse_nested(tb, ILA_NOTIFY_ATTR_MAX, nla,
+ ila_notify_nl_policy);
+
+ if (ret < 0)
+ return ret;
+
+ newts = lwtunnel_state_alloc(encap_len);
+ if (!newts)
+ return -ENOMEM;
+
+ newts->len = 0;
+ newts->type = LWTUNNEL_ENCAP_ILA_NOTIFY;
+ newts->flags |= LWTUNNEL_STATE_OUTPUT_REDIRECT |
+ LWTUNNEL_STATE_INPUT_REDIRECT;
+
+ p = ila_notify_params_lwtunnel(newts);
+
+ if (tb[ILA_NOTIFY_ATTR_TIMEOUT])
+ p->timeout = msecs_to_jiffies(nla_get_u32(
+ tb[ILA_NOTIFY_ATTR_TIMEOUT]));
+
+ *ts = newts;
+
+ return 0;
+}
+
+static int ila_rslv_fill_encap_info(struct sk_buff *skb,
+ struct lwtunnel_state *lwtstate)
+{
+ struct ila_notify_params *p = ila_notify_params_lwtunnel(lwtstate);
+
+ if (nla_put_u32(skb, ILA_NOTIFY_ATTR_TIMEOUT,
+ (__force u32)jiffies_to_msecs(p->timeout)))
+ goto nla_put_failure;
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
+static int ila_rslv_nlsize(struct lwtunnel_state *lwtstate)
+{
+ return nla_total_size(sizeof(u32)) + /* ILA_NOTIFY_ATTR_TIMEOUT */
+ 0;
+}
+
+static int ila_rslv_cmp(struct lwtunnel_state *a, struct lwtunnel_state *b)
+{
+ return 0;
+}
+
+static const struct lwtunnel_encap_ops ila_rslv_ops = {
+ .build_state = ila_rslv_build_state,
+ .output = ila_rslv_output,
+ .input = ila_rslv_input,
+ .fill_encap = ila_rslv_fill_encap_info,
+ .get_encap_size = ila_rslv_nlsize,
+ .cmp_encap = ila_rslv_cmp,
+};
+
+#define ILA_MAX_SIZE 8192
+
+int ila_init_resolver_net(struct ila_net *ilan)
+{
+ ilan->nrslv = net_rslv_create(sizeof(struct ila_addr),
+ sizeof(struct ila_addr), ILA_MAX_SIZE,
+ NULL, NULL, NULL);
+
+ if (!ilan->nrslv)
+ return -ENOMEM;
+
+ return 0;
+}
+
+void ila_exit_resolver_net(struct ila_net *ilan)
+{
+ if (ilan->nrslv)
+ net_rslv_destroy(ilan->nrslv);
+}
+
+int ila_rslv_init(void)
+{
+ return lwtunnel_encap_add_ops(&ila_rslv_ops, LWTUNNEL_ENCAP_ILA_NOTIFY);
+}
+
+void ila_rslv_fini(void)
+{
+ lwtunnel_encap_del_ops(&ila_rslv_ops, LWTUNNEL_ENCAP_ILA_NOTIFY);
+}
diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c
index 7d1c34b..857f8b5 100644
--- a/net/ipv6/ila/ila_xlat.c
+++ b/net/ipv6/ila/ila_xlat.c
@@ -21,14 +21,7 @@ struct ila_map {
struct rcu_head rcu;
};
-static unsigned int ila_net_id;
-
-struct ila_net {
- struct rhashtable rhash_table;
- spinlock_t *locks; /* Bucket locks for entry manipulation */
- unsigned int locks_mask;
- bool hooks_registered;
-};
+unsigned int ila_net_id;
static u32 hashrnd __read_mostly;
static __always_inline void __ila_hash_secret_init(void)
@@ -546,6 +539,10 @@ static __net_init int ila_init_net(struct net *net)
if (err)
return err;
+ /* Resolver net is created on demand when LWT ILA resolver route
+ * is made.
+ */
+
rhashtable_init(&ilan->rhash_table, &rht_params);
return 0;
@@ -557,6 +554,8 @@ static __net_exit void ila_exit_net(struct net *net)
rhashtable_free_and_destroy(&ilan->rhash_table, ila_free_cb, NULL);
+ ila_exit_resolver_net(ilan);
+
free_bucket_spinlocks(ilan->locks);
if (ilan->hooks_registered)
--
2.8.0.rc2
^ permalink raw reply related
* [PATCH net-next 3/7] rhashtable: Call library function alloc_bucket_locks
From: Tom Herbert @ 2016-09-14 23:22 UTC (permalink / raw)
To: davem, netdev; +Cc: tgraf, roopa, kernel-team
In-Reply-To: <1473895376-347096-1-git-send-email-tom@herbertland.com>
To allocate the array of bucket locks for the hash table we now
call library function alloc_bucket_spinlocks. This function is
based on the old alloc_bucket_locks in rhashtable and should
produce the same effect.
Acked-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
lib/rhashtable.c | 46 ++++------------------------------------------
1 file changed, 4 insertions(+), 42 deletions(-)
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 06c2872..5b53304 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -59,50 +59,10 @@ EXPORT_SYMBOL_GPL(lockdep_rht_bucket_is_held);
#define ASSERT_RHT_MUTEX(HT)
#endif
-
-static int alloc_bucket_locks(struct rhashtable *ht, struct bucket_table *tbl,
- gfp_t gfp)
-{
- unsigned int i, size;
-#if defined(CONFIG_PROVE_LOCKING)
- unsigned int nr_pcpus = 2;
-#else
- unsigned int nr_pcpus = num_possible_cpus();
-#endif
-
- nr_pcpus = min_t(unsigned int, nr_pcpus, 64UL);
- size = roundup_pow_of_two(nr_pcpus * ht->p.locks_mul);
-
- /* Never allocate more than 0.5 locks per bucket */
- size = min_t(unsigned int, size, tbl->size >> 1);
-
- if (sizeof(spinlock_t) != 0) {
- tbl->locks = NULL;
-#ifdef CONFIG_NUMA
- if (size * sizeof(spinlock_t) > PAGE_SIZE &&
- gfp == GFP_KERNEL)
- tbl->locks = vmalloc(size * sizeof(spinlock_t));
-#endif
- if (gfp != GFP_KERNEL)
- gfp |= __GFP_NOWARN | __GFP_NORETRY;
-
- if (!tbl->locks)
- tbl->locks = kmalloc_array(size, sizeof(spinlock_t),
- gfp);
- if (!tbl->locks)
- return -ENOMEM;
- for (i = 0; i < size; i++)
- spin_lock_init(&tbl->locks[i]);
- }
- tbl->locks_mask = size - 1;
-
- return 0;
-}
-
static void bucket_table_free(const struct bucket_table *tbl)
{
if (tbl)
- kvfree(tbl->locks);
+ free_bucket_spinlocks(tbl->locks);
kvfree(tbl);
}
@@ -131,7 +91,9 @@ static struct bucket_table *bucket_table_alloc(struct rhashtable *ht,
tbl->size = nbuckets;
- if (alloc_bucket_locks(ht, tbl, gfp) < 0) {
+ /* Never allocate more than 0.5 locks per bucket */
+ if (alloc_bucket_spinlocks(&tbl->locks, &tbl->locks_mask,
+ tbl->size >> 1, ht->p.locks_mul, gfp)) {
bucket_table_free(tbl);
return NULL;
}
--
2.8.0.rc2
^ permalink raw reply related
* [PATCH net-next 1/7] lwt: Add net to build_state argument
From: Tom Herbert @ 2016-09-14 23:22 UTC (permalink / raw)
To: davem, netdev; +Cc: tgraf, roopa, kernel-team
In-Reply-To: <1473895376-347096-1-git-send-email-tom@herbertland.com>
Users of LWT need to know net if they want to have per net operations
in LWT.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
include/net/lwtunnel.h | 10 +++++-----
net/core/lwtunnel.c | 11 +++++++----
net/ipv4/fib_semantics.c | 7 ++++---
net/ipv4/ip_tunnel_core.c | 12 ++++++------
net/ipv6/ila/ila_lwt.c | 6 +++---
net/ipv6/route.c | 2 +-
net/mpls/mpls_iptunnel.c | 6 +++---
7 files changed, 29 insertions(+), 25 deletions(-)
diff --git a/include/net/lwtunnel.h b/include/net/lwtunnel.h
index ea3f80f..3cd6b7c 100644
--- a/include/net/lwtunnel.h
+++ b/include/net/lwtunnel.h
@@ -33,9 +33,9 @@ struct lwtunnel_state {
};
struct lwtunnel_encap_ops {
- int (*build_state)(struct net_device *dev, struct nlattr *encap,
- unsigned int family, const void *cfg,
- struct lwtunnel_state **ts);
+ int (*build_state)(struct net *net, struct net_device *dev,
+ struct nlattr *encap, unsigned int family,
+ const void *cfg, struct lwtunnel_state **ts);
int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
int (*input)(struct sk_buff *skb);
int (*fill_encap)(struct sk_buff *skb,
@@ -106,8 +106,8 @@ int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op,
unsigned int num);
int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
unsigned int num);
-int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
- struct nlattr *encap,
+int lwtunnel_build_state(struct net *net, struct net_device *dev,
+ u16 encap_type, struct nlattr *encap,
unsigned int family, const void *cfg,
struct lwtunnel_state **lws);
int lwtunnel_fill_encap(struct sk_buff *skb,
diff --git a/net/core/lwtunnel.c b/net/core/lwtunnel.c
index e5f84c2..ba8be0b 100644
--- a/net/core/lwtunnel.c
+++ b/net/core/lwtunnel.c
@@ -39,6 +39,8 @@ static const char *lwtunnel_encap_str(enum lwtunnel_encap_types encap_type)
return "MPLS";
case LWTUNNEL_ENCAP_ILA:
return "ILA";
+ case LWTUNNEL_ENCAP_ILA_NOTIFY:
+ return "ILA_NOTIFY";
case LWTUNNEL_ENCAP_IP6:
case LWTUNNEL_ENCAP_IP:
case LWTUNNEL_ENCAP_NONE:
@@ -96,9 +98,10 @@ int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *ops,
}
EXPORT_SYMBOL(lwtunnel_encap_del_ops);
-int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
- struct nlattr *encap, unsigned int family,
- const void *cfg, struct lwtunnel_state **lws)
+int lwtunnel_build_state(struct net *net, struct net_device *dev,
+ u16 encap_type, struct nlattr *encap,
+ unsigned int family, const void *cfg,
+ struct lwtunnel_state **lws)
{
const struct lwtunnel_encap_ops *ops;
int ret = -EINVAL;
@@ -123,7 +126,7 @@ int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
}
#endif
if (likely(ops && ops->build_state))
- ret = ops->build_state(dev, encap, family, cfg, lws);
+ ret = ops->build_state(net, dev, encap, family, cfg, lws);
rcu_read_unlock();
return ret;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 388d3e2..aee4e95 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -511,7 +511,8 @@ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
goto err_inval;
if (cfg->fc_oif)
dev = __dev_get_by_index(net, cfg->fc_oif);
- ret = lwtunnel_build_state(dev, nla_get_u16(
+ ret = lwtunnel_build_state(net, dev,
+ nla_get_u16(
nla_entype),
nla, AF_INET, cfg,
&lwtstate);
@@ -610,7 +611,7 @@ static int fib_encap_match(struct net *net, u16 encap_type,
if (oif)
dev = __dev_get_by_index(net, oif);
- ret = lwtunnel_build_state(dev, encap_type, encap,
+ ret = lwtunnel_build_state(net, dev, encap_type, encap,
AF_INET, cfg, &lwtstate);
if (!ret) {
result = lwtunnel_cmp_encap(lwtstate, nh->nh_lwtstate);
@@ -1098,7 +1099,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
goto err_inval;
if (cfg->fc_oif)
dev = __dev_get_by_index(net, cfg->fc_oif);
- err = lwtunnel_build_state(dev, cfg->fc_encap_type,
+ err = lwtunnel_build_state(net, dev, cfg->fc_encap_type,
cfg->fc_encap, AF_INET, cfg,
&lwtstate);
if (err)
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index 777bc18..6a0cac3 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -239,9 +239,9 @@ static const struct nla_policy ip_tun_policy[LWTUNNEL_IP_MAX + 1] = {
[LWTUNNEL_IP_FLAGS] = { .type = NLA_U16 },
};
-static int ip_tun_build_state(struct net_device *dev, struct nlattr *attr,
- unsigned int family, const void *cfg,
- struct lwtunnel_state **ts)
+static int ip_tun_build_state(struct net *net, struct net_device *dev,
+ struct nlattr *attr, unsigned int family,
+ const void *cfg, struct lwtunnel_state **ts)
{
struct ip_tunnel_info *tun_info;
struct lwtunnel_state *new_state;
@@ -335,9 +335,9 @@ static const struct nla_policy ip6_tun_policy[LWTUNNEL_IP6_MAX + 1] = {
[LWTUNNEL_IP6_FLAGS] = { .type = NLA_U16 },
};
-static int ip6_tun_build_state(struct net_device *dev, struct nlattr *attr,
- unsigned int family, const void *cfg,
- struct lwtunnel_state **ts)
+static int ip6_tun_build_state(struct net *net, struct net_device *dev,
+ struct nlattr *attr, unsigned int family,
+ const void *cfg, struct lwtunnel_state **ts)
{
struct ip_tunnel_info *tun_info;
struct lwtunnel_state *new_state;
diff --git a/net/ipv6/ila/ila_lwt.c b/net/ipv6/ila/ila_lwt.c
index e50c27a..30a6920 100644
--- a/net/ipv6/ila/ila_lwt.c
+++ b/net/ipv6/ila/ila_lwt.c
@@ -56,9 +56,9 @@ static const struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = {
[ILA_ATTR_CSUM_MODE] = { .type = NLA_U8, },
};
-static int ila_build_state(struct net_device *dev, struct nlattr *nla,
- unsigned int family, const void *cfg,
- struct lwtunnel_state **ts)
+static int ila_build_state(struct net *net, struct net_device *dev,
+ struct nlattr *nla, unsigned int family,
+ const void *cfg, struct lwtunnel_state **ts)
{
struct ila_params *p;
struct nlattr *tb[ILA_ATTR_MAX + 1];
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index ad4a7ff..48c3aa7 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1884,7 +1884,7 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg)
if (cfg->fc_encap) {
struct lwtunnel_state *lwtstate;
- err = lwtunnel_build_state(dev, cfg->fc_encap_type,
+ err = lwtunnel_build_state(net, dev, cfg->fc_encap_type,
cfg->fc_encap, AF_INET6, cfg,
&lwtstate);
if (err)
diff --git a/net/mpls/mpls_iptunnel.c b/net/mpls/mpls_iptunnel.c
index cf52cf3..d2df225 100644
--- a/net/mpls/mpls_iptunnel.c
+++ b/net/mpls/mpls_iptunnel.c
@@ -126,9 +126,9 @@ drop:
return -EINVAL;
}
-static int mpls_build_state(struct net_device *dev, struct nlattr *nla,
- unsigned int family, const void *cfg,
- struct lwtunnel_state **ts)
+static int mpls_build_state(struct net *net, struct net_device *dev,
+ struct nlattr *nla, unsigned int family,
+ const void *cfg, struct lwtunnel_state **ts)
{
struct mpls_iptunnel_encap *tun_encap_info;
struct nlattr *tb[MPLS_IPTUNNEL_MAX + 1];
--
2.8.0.rc2
^ permalink raw reply related
* Re: [RFC v3 07/22] landlock: Handle file comparisons
From: Alexei Starovoitov @ 2016-09-14 23:24 UTC (permalink / raw)
To: Mickaël Salaün
Cc: linux-kernel, Alexei Starovoitov, Andy Lutomirski, Arnd Bergmann,
Casey Schaufler, Daniel Borkmann, Daniel Mack, David Drysdale,
David S . Miller, Elena Reshetova, Eric W . Biederman,
James Morris, Kees Cook, Paul Moore, Sargun Dhillon,
Serge E . Hallyn, Tejun Heo, Will Drewry, kernel-hardening,
linux-api, linux-security-module
In-Reply-To: <57D9D6FE.4090708@digikod.net>
On Thu, Sep 15, 2016 at 01:02:22AM +0200, Mickaël Salaün wrote:
> >
> > I would suggest for the next RFC to do minimal 7 patches up to this point
> > with simple example that demonstrates the use case.
> > I would avoid all unpriv stuff and all of seccomp for the next RFC as well,
> > otherwise I don't think we can realistically make forward progress, since
> > there are too many issues raised in the subsequent patches.
>
> I hope we will find a common agreement about seccomp vs cgroup… I think
> both approaches have their advantages, can be complementary and nicely
> combined.
I don't mind having both task based lsm and cgroup based as long as
infrastracture is not duplicated and scaling issues from earlier version
are resolved.
I'm proposing to do cgroup only for the next RFC, since mine and Sargun's
use case for this bpf+lsm+cgroup is _not_ security or sandboxing.
No need for unpriv, no_new_priv to cgroups are other things that Andy
is concerned about.
> Unprivileged sandboxing is the main goal of Landlock. This should not be
> a problem, even for privileged features, thanks to the new subtype/access.
yes. the point that unpriv stuff can come later after agreement is reached.
If we keep arguing about seccomp details this set won't go anywhere.
Even in basic part (which is cgroup+bpf+lsm) are plenty of questions
to be still agreed.
> Agreed. With this RFC, the Checmate features (i.e. network helpers)
> should be able to sit on top of Landlock.
I think neither of them should be called fancy names for no technical reason.
We will have only one bpf based lsm. That's it and it doesn't
need an obscure name. Directory name can be security/bpf/..stuff.c
^ permalink raw reply
* [PATCH net-next 4/7] ila: Call library function alloc_bucket_locks
From: Tom Herbert @ 2016-09-14 23:22 UTC (permalink / raw)
To: davem, netdev; +Cc: tgraf, roopa, kernel-team
In-Reply-To: <1473895376-347096-1-git-send-email-tom@herbertland.com>
To allocate the array of bucket locks for the hash table we now
call library function alloc_bucket_spinlocks.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
net/ipv6/ila/ila_xlat.c | 36 +++++-------------------------------
1 file changed, 5 insertions(+), 31 deletions(-)
diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c
index e604013..7d1c34b 100644
--- a/net/ipv6/ila/ila_xlat.c
+++ b/net/ipv6/ila/ila_xlat.c
@@ -30,34 +30,6 @@ struct ila_net {
bool hooks_registered;
};
-#define LOCKS_PER_CPU 10
-
-static int alloc_ila_locks(struct ila_net *ilan)
-{
- unsigned int i, size;
- unsigned int nr_pcpus = num_possible_cpus();
-
- nr_pcpus = min_t(unsigned int, nr_pcpus, 32UL);
- size = roundup_pow_of_two(nr_pcpus * LOCKS_PER_CPU);
-
- if (sizeof(spinlock_t) != 0) {
-#ifdef CONFIG_NUMA
- if (size * sizeof(spinlock_t) > PAGE_SIZE)
- ilan->locks = vmalloc(size * sizeof(spinlock_t));
- else
-#endif
- ilan->locks = kmalloc_array(size, sizeof(spinlock_t),
- GFP_KERNEL);
- if (!ilan->locks)
- return -ENOMEM;
- for (i = 0; i < size; i++)
- spin_lock_init(&ilan->locks[i]);
- }
- ilan->locks_mask = size - 1;
-
- return 0;
-}
-
static u32 hashrnd __read_mostly;
static __always_inline void __ila_hash_secret_init(void)
{
@@ -561,14 +533,16 @@ static const struct genl_ops ila_nl_ops[] = {
},
};
-#define ILA_HASH_TABLE_SIZE 1024
+#define LOCKS_PER_CPU 10
+#define MAX_LOCKS 1024
static __net_init int ila_init_net(struct net *net)
{
int err;
struct ila_net *ilan = net_generic(net, ila_net_id);
- err = alloc_ila_locks(ilan);
+ err = alloc_bucket_spinlocks(&ilan->locks, &ilan->locks_mask,
+ MAX_LOCKS, LOCKS_PER_CPU, GFP_KERNEL);
if (err)
return err;
@@ -583,7 +557,7 @@ static __net_exit void ila_exit_net(struct net *net)
rhashtable_free_and_destroy(&ilan->rhash_table, ila_free_cb, NULL);
- kvfree(ilan->locks);
+ free_bucket_spinlocks(ilan->locks);
if (ilan->hooks_registered)
nf_unregister_net_hooks(net, ila_nf_hook_ops,
--
2.8.0.rc2
^ permalink raw reply related
* [PATCH net-next 2/7] spinlock: Add library function to allocate spinlock buckets array
From: Tom Herbert @ 2016-09-14 23:22 UTC (permalink / raw)
To: davem, netdev; +Cc: tgraf, roopa, kernel-team
In-Reply-To: <1473895376-347096-1-git-send-email-tom@herbertland.com>
Add two new library functions alloc_bucket_spinlocks and
free_bucket_spinlocks. These are use to allocate and free an array
of spinlocks that are useful as locks for hash buckets. The interface
specifies the maximum number of spinlocks in the array as well
as a CPU multiplier to derive the number of spinlocks to allocate.
The number to allocated is rounded up to a power of two to make
the array amenable to hash lookup.
Reviewed by Greg Rose <grose@lightfleet.com>
Acked-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
include/linux/spinlock.h | 6 +++++
lib/Makefile | 2 +-
lib/bucket_locks.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 70 insertions(+), 1 deletion(-)
create mode 100644 lib/bucket_locks.c
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index 47dd0ce..4ebdfbf 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -416,4 +416,10 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);
#define atomic_dec_and_lock(atomic, lock) \
__cond_lock(lock, _atomic_dec_and_lock(atomic, lock))
+int alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *lock_mask,
+ unsigned int max_size, unsigned int cpu_mult,
+ gfp_t gfp);
+
+void free_bucket_spinlocks(spinlock_t *locks);
+
#endif /* __LINUX_SPINLOCK_H */
diff --git a/lib/Makefile b/lib/Makefile
index 5dc77a8..f91185e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -36,7 +36,7 @@ obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
gcd.o lcm.o list_sort.o uuid.o flex_array.o iov_iter.o clz_ctz.o \
bsearch.o find_bit.o llist.o memweight.o kfifo.o \
percpu-refcount.o percpu_ida.o rhashtable.o reciprocal_div.o \
- once.o
+ once.o bucket_locks.o
obj-y += string_helpers.o
obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o
obj-y += hexdump.o
diff --git a/lib/bucket_locks.c b/lib/bucket_locks.c
new file mode 100644
index 0000000..bb9bf11
--- /dev/null
+++ b/lib/bucket_locks.c
@@ -0,0 +1,63 @@
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
+#include <linux/export.h>
+
+/* Allocate an array of spinlocks to be accessed by a hash. Two arguments
+ * indicate the number of elements to allocate in the array. max_size
+ * gives the maximum number of elements to allocate. cpu_mult gives
+ * the number of locks per CPU to allocate. The size is rounded up
+ * to a power of 2 to be suitable as a hash table.
+ */
+int alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *locks_mask,
+ unsigned int max_size, unsigned int cpu_mult,
+ gfp_t gfp)
+{
+ unsigned int i, size;
+#if defined(CONFIG_PROVE_LOCKING)
+ unsigned int nr_pcpus = 2;
+#else
+ unsigned int nr_pcpus = num_possible_cpus();
+#endif
+ spinlock_t *tlocks = NULL;
+
+ if (cpu_mult) {
+ nr_pcpus = min_t(unsigned int, nr_pcpus, 64UL);
+ size = min_t(unsigned int, nr_pcpus * cpu_mult, max_size);
+ } else {
+ size = max_size;
+ }
+ size = roundup_pow_of_two(size);
+
+ if (!size)
+ return -EINVAL;
+
+ if (sizeof(spinlock_t) != 0) {
+#ifdef CONFIG_NUMA
+ if (size * sizeof(spinlock_t) > PAGE_SIZE &&
+ gfp == GFP_KERNEL)
+ tlocks = vmalloc(size * sizeof(spinlock_t));
+#endif
+ if (gfp != GFP_KERNEL)
+ gfp |= __GFP_NOWARN | __GFP_NORETRY;
+
+ if (!tlocks)
+ tlocks = kmalloc_array(size, sizeof(spinlock_t), gfp);
+ if (!tlocks)
+ return -ENOMEM;
+ for (i = 0; i < size; i++)
+ spin_lock_init(&tlocks[i]);
+ }
+ *locks = tlocks;
+ *locks_mask = size - 1;
+
+ return 0;
+}
+EXPORT_SYMBOL(alloc_bucket_spinlocks);
+
+void free_bucket_spinlocks(spinlock_t *locks)
+{
+ kvfree(locks);
+}
+EXPORT_SYMBOL(free_bucket_spinlocks);
--
2.8.0.rc2
^ permalink raw reply related
* [PATCH net-next 0/7] net: ILA resolver and generic resolver backend
From: Tom Herbert @ 2016-09-14 23:22 UTC (permalink / raw)
To: davem, netdev; +Cc: tgraf, roopa, kernel-team
This patch set implements an ILA host side resolver. This uses LWT to
implement the hook to a userspace resolver and tracks pending unresolved
address using the backend net resolver.
This patch set contains:
- An new library function to allocate an array of spinlocks for use
with locking hash buckets.
- Make hash function in rhashtable directly callable.
- A generic resolver backend infrastructure. This primary does two
things: track unsesolved addresses and implement a timeout for
resolution not happening. These mechanisms provides rate limiting
control over resolution requests (for instance in ILA it use used
to rate limit requests to userspace to resolve addresses).
- The ILA resolver. This is implements to path from the kernel ILA
implementation to a userspace daemon that an identifier address
needs to be resolved.
- Routing messages are used over netlink to indicate resoltion
requests.
Changes from intial RFC:
- Added net argument to LWT build_state
- Made resolve timeout an attribute of the LWT encap route
- Changed ILA notifications to be regular routing messages of event
RTM_ADDR_RESOLVE, family RTNL_FAMILY_ILA, and group
RTNLGRP_ILA_NOTIFY
Tested:
- Ran a UDP flood to random addresses in a resolver prefix. Observed
timeout and limits were working (watching "ip monitor").
- Also ran against an ILA client daemon that runs the resolver
protocol. Observed that when resolution completes (ILA encap route is
installed) routing messages are no longer sent.
Tom Herbert (7):
lwt: Add net to build_state argument
spinlock: Add library function to allocate spinlock buckets array
rhashtable: Call library function alloc_bucket_locks
ila: Call library function alloc_bucket_locks
rhashtable: abstract out function to get hash
net: Generic resolver backend
ila: Resolver mechanism
include/linux/rhashtable.h | 28 +++--
include/linux/spinlock.h | 6 +
include/net/lwtunnel.h | 10 +-
include/net/resolver.h | 58 +++++++++
include/uapi/linux/ila.h | 9 ++
include/uapi/linux/lwtunnel.h | 1 +
include/uapi/linux/rtnetlink.h | 8 +-
lib/Makefile | 2 +-
lib/bucket_locks.c | 63 ++++++++++
lib/rhashtable.c | 46 +------
net/Kconfig | 4 +
net/core/Makefile | 1 +
net/core/lwtunnel.c | 11 +-
net/core/resolver.c | 268 +++++++++++++++++++++++++++++++++++++++++
net/ipv4/fib_semantics.c | 7 +-
net/ipv4/ip_tunnel_core.c | 12 +-
net/ipv6/Kconfig | 1 +
net/ipv6/ila/Makefile | 2 +-
net/ipv6/ila/ila.h | 16 +++
net/ipv6/ila/ila_common.c | 7 ++
net/ipv6/ila/ila_lwt.c | 15 ++-
net/ipv6/ila/ila_resolver.c | 246 +++++++++++++++++++++++++++++++++++++
net/ipv6/ila/ila_xlat.c | 51 ++------
net/ipv6/route.c | 2 +-
net/mpls/mpls_iptunnel.c | 6 +-
25 files changed, 761 insertions(+), 119 deletions(-)
create mode 100644 include/net/resolver.h
create mode 100644 lib/bucket_locks.c
create mode 100644 net/core/resolver.c
create mode 100644 net/ipv6/ila/ila_resolver.c
--
2.8.0.rc2
^ permalink raw reply
* [PATCH net-next 5/7] rhashtable: abstract out function to get hash
From: Tom Herbert @ 2016-09-14 23:22 UTC (permalink / raw)
To: davem, netdev; +Cc: tgraf, roopa, kernel-team
In-Reply-To: <1473895376-347096-1-git-send-email-tom@herbertland.com>
Split out most of rht_key_hashfn which is calculating the hash into
its own function. This way the hash function can be called separately to
get the hash value.
Acked-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
include/linux/rhashtable.h | 28 ++++++++++++++++++----------
1 file changed, 18 insertions(+), 10 deletions(-)
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index fd82584..e398a62 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -208,34 +208,42 @@ static inline unsigned int rht_bucket_index(const struct bucket_table *tbl,
return (hash >> RHT_HASH_RESERVED_SPACE) & (tbl->size - 1);
}
-static inline unsigned int rht_key_hashfn(
- struct rhashtable *ht, const struct bucket_table *tbl,
- const void *key, const struct rhashtable_params params)
+static inline unsigned int rht_key_get_hash(struct rhashtable *ht,
+ const void *key, const struct rhashtable_params params,
+ unsigned int hash_rnd)
{
unsigned int hash;
/* params must be equal to ht->p if it isn't constant. */
if (!__builtin_constant_p(params.key_len))
- hash = ht->p.hashfn(key, ht->key_len, tbl->hash_rnd);
+ hash = ht->p.hashfn(key, ht->key_len, hash_rnd);
else if (params.key_len) {
unsigned int key_len = params.key_len;
if (params.hashfn)
- hash = params.hashfn(key, key_len, tbl->hash_rnd);
+ hash = params.hashfn(key, key_len, hash_rnd);
else if (key_len & (sizeof(u32) - 1))
- hash = jhash(key, key_len, tbl->hash_rnd);
+ hash = jhash(key, key_len, hash_rnd);
else
- hash = jhash2(key, key_len / sizeof(u32),
- tbl->hash_rnd);
+ hash = jhash2(key, key_len / sizeof(u32), hash_rnd);
} else {
unsigned int key_len = ht->p.key_len;
if (params.hashfn)
- hash = params.hashfn(key, key_len, tbl->hash_rnd);
+ hash = params.hashfn(key, key_len, hash_rnd);
else
- hash = jhash(key, key_len, tbl->hash_rnd);
+ hash = jhash(key, key_len, hash_rnd);
}
+ return hash;
+}
+
+static inline unsigned int rht_key_hashfn(
+ struct rhashtable *ht, const struct bucket_table *tbl,
+ const void *key, const struct rhashtable_params params)
+{
+ unsigned int hash = rht_key_get_hash(ht, key, params, tbl->hash_rnd);
+
return rht_bucket_index(tbl, hash);
}
--
2.8.0.rc2
^ permalink raw reply related
* Claris Job
From: 茹水牛 @ 2016-09-14 23:16 UTC (permalink / raw)
To: netdev
From: 茹水牛
Email: brimskin@gator3201.hostgator.com
Message:
【澳门金沙集团】精湛服务,轻松投注!游戏丰富,赛事超多!
天天返水1.2%,全网注单0审核,账户0冻结,出入款0延迟!
9年诚信经营品牌,全程担保网址:http://www.834516.com/?netdev@vger.kernel.org
怕黑庄,请上澳门金沙集团,一家只做好博彩的公司。
------------------------------------------
你要知道梨子的味道!你就得变革梨子!亲口吃一吃。
---
Job Title: Email A Friend
Url:
^ permalink raw reply
* [PATCH net-next 6/7] net: Generic resolver backend
From: Tom Herbert @ 2016-09-14 23:22 UTC (permalink / raw)
To: davem, netdev; +Cc: tgraf, roopa, kernel-team
In-Reply-To: <1473895376-347096-1-git-send-email-tom@herbertland.com>
This patch implements the backend of a resolver, specifically it
provides a means to track unresolved addresses and to time them out.
The resolver is mostly a frontend to an rhashtable where the key
of the table is whatever address type or object is tracked. A resolver
instance is created by net_rslv_create. A resolver is destroyed by
net_rslv_destroy.
There are two functions that are used to manipulate entries in the
table: net_rslv_lookup_and_create and net_rslv_resolved.
net_rslv_lookup_and_create is called with an unresolved address as
the argument. It returns a structure of type net_rslv_ent. When
called a lookup is performed to see if an entry for the address
is already in the table, if it is the entry is return and the
false is returned in the new bool pointer argument to indicate that
the entry was preexisting. If an entry is not found, one is create
and true is returned on the new pointer argument. It is expected
that when an entry is new the address resolution protocol is
initiated (for instance a RTM_ADDR_RESOLVE message may be sent to a
userspace daemon as we will do in ILA). If net_rslv_lookup_and_create
returns NULL then presumably the hash table has reached the limit of
number of outstanding unresolved addresses, the caller should take
appropriate actions to avoid spamming the resolution protocol.
net_rslv_resolved is called when resolution is completely (e.g.
ILA locator mapping was instantiated for a locator. The entry is
removed for the hash table.
An argument to net_rslv_create indicates a time for the pending
resolution in milliseconds. If the timer fires before resolution
then the entry is removed from the table. Subsequently, another
attempt to resolve the same address will result in a new entry in
the table.
net_rslv_lookup_and_create allocates an net_rslv_ent struct and
includes allocating related user data. This is the object[] field
in the structure. The key (unresolved address) is always the first
field in the the object. Following that the caller may add it's
own private field data. The key length and size of the user object
(including the key) are specific in net_rslv_create.
There are three callback functions that can be set as arugments in
net_rslv_create:
- cmp_fn: Compare function for hash table. Arguments are the
key and an object in the table. If this is NULL then the
default memcmp of rhashtable is used.
- init_fn: Initial a new net_rslv_ent structure. This allows
initialization of the user portion of the structure
(the object[]).
- destroy_fn: Called right before a net_rslv_ent is freed.
This allows cleanup of user data associated with the
entry.
Note that the resolver backend only tracks unresolved addresses, it
is up to the caller to perform the mechanism of resolution. This
includes the possible of queuing packets awaiting resolution; this
can be accomplished for instance by maintaining an skbuff queue
in the net_rslv_ent user object[] data.
DOS mitigation is done by limiting the number of entries in the
resolver table (the max_size which argument of net_rslv_create)
and setting a timeout. IF the timeout is set then the maximum rate
of new resolution requests is max_table_size / timeout. For
instance, with a maximum size of 1000 entries and a timeout of 100
msecs the maximum rate of resolutions requests is 10000/s.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
include/net/resolver.h | 58 +++++++++++
net/Kconfig | 4 +
net/core/Makefile | 1 +
net/core/resolver.c | 268 +++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 331 insertions(+)
create mode 100644 include/net/resolver.h
create mode 100644 net/core/resolver.c
diff --git a/include/net/resolver.h b/include/net/resolver.h
new file mode 100644
index 0000000..9274237
--- /dev/null
+++ b/include/net/resolver.h
@@ -0,0 +1,58 @@
+#ifndef __NET_RESOLVER_H
+#define __NET_RESOLVER_H
+
+#include <linux/rhashtable.h>
+
+struct net_rslv;
+struct net_rslv_ent;
+
+typedef int (*net_rslv_cmpfn)(struct net_rslv *nrslv, const void *key,
+ const void *object);
+typedef void (*net_rslv_initfn)(struct net_rslv *nrslv, void *object);
+typedef void (*net_rslv_destroyfn)(struct net_rslv_ent *nrent);
+
+struct net_rslv {
+ struct rhashtable rhash_table;
+ struct rhashtable_params params;
+ net_rslv_cmpfn rslv_cmp;
+ net_rslv_initfn rslv_init;
+ net_rslv_destroyfn rslv_destroy;
+ size_t obj_size;
+ spinlock_t *locks;
+ unsigned int locks_mask;
+ unsigned int hash_rnd;
+};
+
+struct net_rslv_ent {
+ struct rcu_head rcu;
+ union {
+ /* Fields set when entry is in hash table */
+ struct {
+ struct rhash_head node;
+ struct delayed_work timeout_work;
+ struct net_rslv *nrslv;
+ };
+
+ /* Fields set when rcu freeing structure */
+ struct {
+ net_rslv_destroyfn destroy;
+ };
+ };
+ char object[];
+};
+
+struct net_rslv *net_rslv_create(size_t size, size_t key_len,
+ size_t max_size,
+ net_rslv_cmpfn cmp_fn,
+ net_rslv_initfn init_fn,
+ net_rslv_destroyfn destroy_fn);
+
+struct net_rslv_ent *net_rslv_lookup_and_create(struct net_rslv *nrslv,
+ void *key, bool *created,
+ unsigned int timeout);
+
+void net_rslv_resolved(struct net_rslv *nrslv, void *key);
+
+void net_rslv_destroy(struct net_rslv *nrslv);
+
+#endif
diff --git a/net/Kconfig b/net/Kconfig
index 7b6cd34..fad4fac 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -255,6 +255,10 @@ config XPS
depends on SMP
default y
+config NET_EXT_RESOLVER
+ bool
+ default n
+
config HWBM
bool
diff --git a/net/core/Makefile b/net/core/Makefile
index d6508c2..c0a0208 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -27,3 +27,4 @@ obj-$(CONFIG_LWTUNNEL) += lwtunnel.o
obj-$(CONFIG_DST_CACHE) += dst_cache.o
obj-$(CONFIG_HWBM) += hwbm.o
obj-$(CONFIG_NET_DEVLINK) += devlink.o
+obj-$(CONFIG_NET_EXT_RESOLVER) += resolver.o
diff --git a/net/core/resolver.c b/net/core/resolver.c
new file mode 100644
index 0000000..44f42e2
--- /dev/null
+++ b/net/core/resolver.c
@@ -0,0 +1,268 @@
+#include <linux/errno.h>
+#include <linux/ip.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netlink.h>
+#include <linux/skbuff.h>
+#include <linux/socket.h>
+#include <linux/types.h>
+#include <linux/vmalloc.h>
+#include <net/checksum.h>
+#include <net/ip.h>
+#include <net/ip6_fib.h>
+#include <net/lwtunnel.h>
+#include <net/protocol.h>
+#include <net/resolver.h>
+#include <uapi/linux/ila.h>
+
+static void net_rslv_destroy_rcu(struct rcu_head *head)
+{
+ struct net_rslv_ent *nrent = container_of(head, struct net_rslv_ent,
+ rcu);
+ if (nrent->destroy) {
+ /* Call user's destroy function just before freeing */
+ nrent->destroy(nrent);
+ }
+
+ kfree(nrent);
+}
+
+static void net_rslv_destroy_entry(struct net_rslv *nrslv,
+ struct net_rslv_ent *nrent)
+{
+ nrent->destroy = nrslv->rslv_destroy;
+ call_rcu(&nrent->rcu, net_rslv_destroy_rcu);
+}
+
+static inline spinlock_t *net_rslv_get_lock(struct net_rslv *nrslv, void *key)
+{
+ unsigned int hash;
+
+ /* Use the rhashtable hash function */
+ hash = rht_key_get_hash(&nrslv->rhash_table, key, nrslv->params,
+ nrslv->hash_rnd);
+
+ return &nrslv->locks[hash & nrslv->locks_mask];
+}
+
+static void net_rslv_delayed_work(struct work_struct *w)
+{
+ struct delayed_work *delayed_work = to_delayed_work(w);
+ struct net_rslv_ent *nrent = container_of(delayed_work,
+ struct net_rslv_ent,
+ timeout_work);
+ struct net_rslv *nrslv = nrent->nrslv;
+ spinlock_t *lock = net_rslv_get_lock(nrslv, nrent->object);
+
+ spin_lock(lock);
+ rhashtable_remove_fast(&nrslv->rhash_table, &nrent->node,
+ nrslv->params);
+ spin_unlock(lock);
+
+ net_rslv_destroy_entry(nrslv, nrent);
+}
+
+static void net_rslv_ent_free_cb(void *ptr, void *arg)
+{
+ struct net_rslv_ent *nrent = (struct net_rslv_ent *)ptr;
+ struct net_rslv *nrslv = nrent->nrslv;
+
+ net_rslv_destroy_entry(nrslv, nrent);
+}
+
+void net_rslv_resolved(struct net_rslv *nrslv, void *key)
+{
+ spinlock_t *lock = net_rslv_get_lock(nrslv, key);
+ struct net_rslv_ent *nrent;
+
+ rcu_read_lock();
+
+ nrent = rhashtable_lookup_fast(&nrslv->rhash_table, key,
+ nrslv->params);
+ if (!nrent)
+ goto out;
+
+ /* Cancel timer first */
+ cancel_delayed_work_sync(&nrent->timeout_work);
+
+ spin_lock(lock);
+
+ /* Lookup again just in case someone already removed */
+ nrent = rhashtable_lookup_fast(&nrslv->rhash_table, key,
+ nrslv->params);
+ if (unlikely(!nrent)) {
+ spin_unlock(lock);
+ goto out;
+ }
+
+ rhashtable_remove_fast(&nrslv->rhash_table, &nrent->node,
+ nrslv->params);
+ spin_unlock(lock);
+
+ net_rslv_destroy_entry(nrslv, nrent);
+
+out:
+ rcu_read_unlock();
+}
+EXPORT_SYMBOL_GPL(net_rslv_resolved);
+
+/* Called with hash bucket lock held */
+static struct net_rslv_ent *net_rslv_new_ent(struct net_rslv *nrslv,
+ void *key, unsigned int timeout)
+{
+ struct net_rslv_ent *nrent;
+ int err;
+
+ nrent = kzalloc(sizeof(*nrent) + nrslv->obj_size, GFP_KERNEL);
+ if (!nrent)
+ return ERR_PTR(-EAGAIN);
+
+ /* Key is always at beginning of object data */
+ memcpy(nrent->object, key, nrslv->params.key_len);
+
+ nrent->nrslv = nrslv;
+
+ /* Initialize user data */
+ if (nrslv->rslv_init)
+ nrslv->rslv_init(nrslv, nrent);
+
+ /* Put in hash table */
+ err = rhashtable_lookup_insert_fast(&nrslv->rhash_table,
+ &nrent->node, nrslv->params);
+ if (err)
+ return ERR_PTR(err);
+
+ if (timeout) {
+ /* Schedule timeout for resolver */
+ INIT_DELAYED_WORK(&nrent->timeout_work, net_rslv_delayed_work);
+ schedule_delayed_work(&nrent->timeout_work, timeout);
+ }
+
+ return nrent;
+}
+
+struct net_rslv_ent *net_rslv_lookup_and_create(struct net_rslv *nrslv,
+ void *key, bool *created,
+ unsigned int timeout)
+{
+ spinlock_t *lock = net_rslv_get_lock(nrslv, key);
+ struct net_rslv_ent *nrent;
+
+ *created = false;
+ nrent = rhashtable_lookup_fast(&nrslv->rhash_table, key,
+ nrslv->params);
+ if (nrent)
+ return nrent;
+
+ spin_lock(lock);
+
+ /* Check if someone beat us to the punch */
+ nrent = rhashtable_lookup_fast(&nrslv->rhash_table, key,
+ nrslv->params);
+ if (nrent) {
+ spin_unlock(lock);
+ return nrent;
+ }
+
+ nrent = net_rslv_new_ent(nrslv, key, timeout);
+
+ spin_unlock(lock);
+
+ *created = true;
+
+ return nrent;
+}
+EXPORT_SYMBOL_GPL(net_rslv_lookup_and_create);
+
+static int net_rslv_cmp(struct rhashtable_compare_arg *arg,
+ const void *obj)
+{
+ struct net_rslv *nrslv = container_of(arg->ht, struct net_rslv,
+ rhash_table);
+
+ return nrslv->rslv_cmp(nrslv, arg->key, obj);
+}
+
+#define LOCKS_PER_CPU 10
+#define MAX_LOCKS 1024
+
+struct net_rslv *net_rslv_create(size_t obj_size, size_t key_len,
+ size_t max_size,
+ net_rslv_cmpfn cmp_fn,
+ net_rslv_initfn init_fn,
+ net_rslv_destroyfn destroy_fn)
+{
+ struct net_rslv *nrslv;
+ int err;
+
+ if (key_len < obj_size)
+ return ERR_PTR(-EINVAL);
+
+ nrslv = kzalloc(sizeof(*nrslv), GFP_KERNEL);
+ if (!nrslv)
+ return ERR_PTR(-ENOMEM);
+
+ err = alloc_bucket_spinlocks(&nrslv->locks, &nrslv->locks_mask,
+ MAX_LOCKS, LOCKS_PER_CPU, GFP_KERNEL);
+ if (err)
+ return ERR_PTR(err);
+
+ nrslv->obj_size = obj_size;
+ nrslv->rslv_init = init_fn;
+ nrslv->rslv_cmp = cmp_fn;
+ nrslv->rslv_destroy = destroy_fn;
+ get_random_bytes(&nrslv->hash_rnd, sizeof(nrslv->hash_rnd));
+
+ nrslv->params.head_offset = offsetof(struct net_rslv_ent, node);
+ nrslv->params.key_offset = offsetof(struct net_rslv_ent, object);
+ nrslv->params.key_len = key_len;
+ nrslv->params.max_size = max_size;
+ nrslv->params.min_size = 256;
+ nrslv->params.automatic_shrinking = true;
+ nrslv->params.obj_cmpfn = cmp_fn ? net_rslv_cmp : NULL;
+
+ rhashtable_init(&nrslv->rhash_table, &nrslv->params);
+
+ return nrslv;
+}
+EXPORT_SYMBOL_GPL(net_rslv_create);
+
+static void net_rslv_cancel_all_delayed_work(struct net_rslv *nrslv)
+{
+ struct rhashtable_iter iter;
+ struct net_rslv_ent *nrent;
+ int ret;
+
+ ret = rhashtable_walk_init(&nrslv->rhash_table, &iter, GFP_ATOMIC);
+ if (WARN_ON(ret))
+ return;
+
+ ret = rhashtable_walk_start(&iter);
+ if (WARN_ON(ret && ret != -EAGAIN))
+ goto err;
+
+ while ((nrent = rhashtable_walk_next(&iter)))
+ cancel_delayed_work_sync(&nrent->timeout_work);
+
+err:
+ rhashtable_walk_stop(&iter);
+ rhashtable_walk_exit(&iter);
+}
+
+void net_rslv_destroy(struct net_rslv *nrslv)
+{
+ /* First cancel delayed work in all the nodes. We don't want
+ * delayed work trying to remove nodes from the table while
+ * rhashtable_free_and_destroy is walking.
+ */
+ net_rslv_cancel_all_delayed_work(nrslv);
+
+ rhashtable_free_and_destroy(&nrslv->rhash_table,
+ net_rslv_ent_free_cb, NULL);
+
+ free_bucket_spinlocks(nrslv->locks);
+
+ kfree(nrslv);
+}
+EXPORT_SYMBOL_GPL(net_rslv_destroy);
+
--
2.8.0.rc2
^ permalink raw reply related
* Re: [RFC v3 03/22] bpf,landlock: Add a new arraymap type to deal with (Landlock) handles
From: Mickaël Salaün @ 2016-09-14 23:22 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: linux-kernel, Alexei Starovoitov, Andy Lutomirski, Arnd Bergmann,
Casey Schaufler, Daniel Borkmann, Daniel Mack, David Drysdale,
David S . Miller, Elena Reshetova, Eric W . Biederman,
James Morris, Kees Cook, Paul Moore, Sargun Dhillon,
Serge E . Hallyn, Tejun Heo, Will Drewry, kernel-hardening,
linux-api, linux-security-module, netdev
In-Reply-To: <20160914185157.GA53542@ast-mbp.thefacebook.com>
[-- Attachment #1.1: Type: text/plain, Size: 5140 bytes --]
On 14/09/2016 20:51, Alexei Starovoitov wrote:
> On Wed, Sep 14, 2016 at 09:23:56AM +0200, Mickaël Salaün wrote:
>> This new arraymap looks like a set and brings new properties:
>> * strong typing of entries: the eBPF functions get the array type of
>> elements instead of CONST_PTR_TO_MAP (e.g.
>> CONST_PTR_TO_LANDLOCK_HANDLE_FS);
>> * force sequential filling (i.e. replace or append-only update), which
>> allow quick browsing of all entries.
>>
>> This strong typing is useful to statically check if the content of a map
>> can be passed to an eBPF function. For example, Landlock use it to store
>> and manage kernel objects (e.g. struct file) instead of dealing with
>> userland raw data. This improve efficiency and ensure that an eBPF
>> program can only call functions with the right high-level arguments.
>>
>> The enum bpf_map_handle_type list low-level types (e.g.
>> BPF_MAP_HANDLE_TYPE_LANDLOCK_FS_FD) which are identified when
>> updating a map entry (handle). This handle types are used to infer a
>> high-level arraymap type which are listed in enum bpf_map_array_type
>> (e.g. BPF_MAP_ARRAY_TYPE_LANDLOCK_FS).
>>
>> For now, this new arraymap is only used by Landlock LSM (cf. next
>> commits) but it could be useful for other needs.
>>
>> Changes since v2:
>> * add a RLIMIT_NOFILE-based limit to the maximum number of arraymap
>> handle entries (suggested by Andy Lutomirski)
>> * remove useless checks
>>
>> Changes since v1:
>> * arraymap of handles replace custom checker groups
>> * simpler userland API
>>
>> Signed-off-by: Mickaël Salaün <mic@digikod.net>
>> Cc: Alexei Starovoitov <ast@kernel.org>
>> Cc: Andy Lutomirski <luto@amacapital.net>
>> Cc: Daniel Borkmann <daniel@iogearbox.net>
>> Cc: David S. Miller <davem@davemloft.net>
>> Cc: Kees Cook <keescook@chromium.org>
>> Link: https://lkml.kernel.org/r/CALCETrWwTiz3kZTkEgOW24-DvhQq6LftwEXh77FD2G5o71yD7g@mail.gmail.com
>> ---
>> include/linux/bpf.h | 14 ++++
>> include/uapi/linux/bpf.h | 18 +++++
>> kernel/bpf/arraymap.c | 203 +++++++++++++++++++++++++++++++++++++++++++++++
>> kernel/bpf/verifier.c | 12 ++-
>> 4 files changed, 246 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
>> index fa9a988400d9..eae4ce4542c1 100644
>> --- a/include/linux/bpf.h
>> +++ b/include/linux/bpf.h
>> @@ -13,6 +13,10 @@
>> #include <linux/percpu.h>
>> #include <linux/err.h>
>>
>> +#ifdef CONFIG_SECURITY_LANDLOCK
>> +#include <linux/fs.h> /* struct file */
>> +#endif /* CONFIG_SECURITY_LANDLOCK */
>> +
>> struct perf_event;
>> struct bpf_map;
>>
>> @@ -38,6 +42,7 @@ struct bpf_map_ops {
>> struct bpf_map {
>> atomic_t refcnt;
>> enum bpf_map_type map_type;
>> + enum bpf_map_array_type map_array_type;
>> u32 key_size;
>> u32 value_size;
>> u32 max_entries;
>> @@ -187,6 +192,9 @@ struct bpf_array {
>> */
>> enum bpf_prog_type owner_prog_type;
>> bool owner_jited;
>> +#ifdef CONFIG_SECURITY_LANDLOCK
>> + u32 n_entries; /* number of entries in a handle array */
>> +#endif /* CONFIG_SECURITY_LANDLOCK */
>> union {
>> char value[0] __aligned(8);
>> void *ptrs[0] __aligned(8);
>> @@ -194,6 +202,12 @@ struct bpf_array {
>> };
>> };
>>
>> +#ifdef CONFIG_SECURITY_LANDLOCK
>> +struct map_landlock_handle {
>> + u32 type; /* enum bpf_map_handle_type */
>> +};
>> +#endif /* CONFIG_SECURITY_LANDLOCK */
>> +
>> #define MAX_TAIL_CALL_CNT 32
>>
>> struct bpf_event_entry {
>> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
>> index 7cd36166f9b7..b68de57f7ab8 100644
>> --- a/include/uapi/linux/bpf.h
>> +++ b/include/uapi/linux/bpf.h
>> @@ -87,6 +87,15 @@ enum bpf_map_type {
>> BPF_MAP_TYPE_PERCPU_ARRAY,
>> BPF_MAP_TYPE_STACK_TRACE,P_TYPE_CGROUP_ARRAY
>> BPF_MAP_TYPE_CGROUP_ARRAY,
>> + BPF_MAP_TYPE_LANDLOCK_ARRAY,
>> +};
>> +
>> +enum bpf_map_array_type {
>> + BPF_MAP_ARRAY_TYPE_UNSPEC,
>> +};
>> +
>> +enum bpf_map_handle_type {
>> + BPF_MAP_HANDLE_TYPE_UNSPEC,
>> };
>
> missing something. why it has to be special to have it's own
> fd array implementation?
> Please take a look how BPF_MAP_TYPE_PERF_EVENT_ARRAY,
> BPF_MAP_TYPE_CGROUP_ARRAY and BPF_MAP_TYPE_PROG_ARRAY are done.
> The all store objects into array map that user space passes via FD.
> I think the same model should apply here.
The idea is to have multiple way for userland to describe a resource
(e.g. an open file descriptor, a path or a glob pattern). The kernel
representation could then be a "struct path *" or dedicated types (e.g.
custom glob).
Another interesting point (that could replace
check_map_func_compatibility()) is that BPF_MAP_TYPE_LANDLOCK_ARRAY
translate to dedicated (abstract) types (instead of CONST_PTR_TO_MAP)
thanks to bpf_reg_type_from_map(). This is useful to abstract userland
(map) interface with kernel object(s) dealing with that type.
A third point is that BPF_MAP_TYPE_LANDLOCK_ARRAY is a kind of set. It
is optimized to quickly walk through all the elements in a sequential way.
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 455 bytes --]
^ permalink raw reply
* Re: [RFC 3/3] phy,leds: add support for led triggers on phy link state change
From: Florian Fainelli @ 2016-09-14 23:16 UTC (permalink / raw)
To: Zach Brown
Cc: mlindner, stephen, netdev, linux-kernel, devel,
florian.c.schilhabel, Larry.Finger
In-Reply-To: <1473890149-2066-4-git-send-email-zach.brown@ni.com>
On 09/14/2016 02:55 PM, Zach Brown wrote:
> From: Josh Cartwright <josh.cartwright@ni.com>
>
> Create an option CONFIG_LED_TRIGGER_PHY (default n), which will
> create a set of led triggers for each instantiated PHY device. There is
> one LED trigger per link-speed, per-phy.
>
> This allows for a user to configure their system to allow a set of LEDs
> to represent link state changes on the phy.
The part that seems to be missing from this changeset (not an issue) is
how you can "accelerate" the triggers, or rather make sure that the
trigger configuration potentially calls back into the PHY driver when
the requested trigger is actually supported by the on-PHY LEDs.
Other than that, just minor nits here and there.
>
> Signed-off-by: Josh Cartwright <josh.cartwright@ni.com>
> Signed-off-by: Nathan Sullivan <nathan.sullivan@ni.com>
> Signed-off-by: Zach Brown <zach.brown@ni.com>
> ---
> +config LED_TRIGGER_PHY
> + bool "Support LED triggers for tracking link state"
> + depends on LEDS_TRIGGERS
> + ---help---
> + Adds support for a set of LED trigger events per-PHY. Link
> + state change will trigger the events, for consumption by an
> + LED class driver. There are triggers for each link speed,
> + and are of the form:
> + <mii bus id>:<phy>:<speed>
> +
> + Where speed is one of: 10Mb, 100Mb, Gb, 2.5Gb, or 10GbE.
I would do s/10GbE/10Gb/ just to be consistent with the other speeds, or
maybe, to avoid too much duplicationg of how we represent speeds, use
the same set of strings that drivers/net/phy/phy.c::phy_speed_to_str uses.
> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
> index c6f6683..3345767 100644
> --- a/drivers/net/phy/phy.c
> +++ b/drivers/net/phy/phy.c
> @@ -936,6 +936,7 @@ void phy_state_machine(struct work_struct *work)
> phydev->state = PHY_NOLINK;
> netif_carrier_off(phydev->attached_dev);
> phydev->adjust_link(phydev->attached_dev);
> + phy_led_trigger_change_speed(phydev);
Since we have essentially two actions to take when performing link state
changes:
- call the adjust_link callback
- call into the LED trigger
we might consider encapsulating this into a function that could be named
phy_adjust_link() and does both of these. That would be a preliminary
patch to this this one.
>
> @@ -345,6 +347,8 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
>
> dev->state = PHY_DOWN;
>
> + phy_led_triggers_register(dev);
> +
> mutex_init(&dev->lock);
> INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
> INIT_WORK(&dev->phy_queue, phy_change);
Humm, should it be before the PHY state machine workqueue creation or
after? Just wondering if there is a remote chance we could get an user
to immediately program a trigger and this could create a problem, maybe
not so much.
> diff --git a/drivers/net/phy/phy_led_triggers.c b/drivers/net/phy/phy_led_triggers.c
> new file mode 100644
> index 0000000..6c40414
> --- /dev/null
> +++ b/drivers/net/phy/phy_led_triggers.c
> @@ -0,0 +1,109 @@
> +/* Copyright (C) 2016 National Instruments Corp.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +#include <linux/leds.h>
> +#include <linux/phy.h>
> +
> +void phy_led_trigger_change_speed(struct phy_device *phy)
> +{
> + struct phy_led_trigger *plt;
> +
> + if (!phy->link) {
> + if (phy->last_triggered) {
> + led_trigger_event(&phy->last_triggered->trigger,
> + LED_OFF);
> + phy->last_triggered = NULL;
> + }
> + return;
> + }
> +
> + switch (phy->speed) {
> + case SPEED_10:
> + plt = &phy->phy_led_trigger[0];
> + break;
> + case SPEED_100:
> + plt = &phy->phy_led_trigger[1];
> + break;
> + case SPEED_1000:
> + plt = &phy->phy_led_trigger[2];
> + break;
> + case SPEED_2500:
> + plt = &phy->phy_led_trigger[3];
> + break;
> + case SPEED_10000:
> + plt = &phy->phy_led_trigger[4];
> + break;
We could use a table here indexed by the speed, or have a function that
does phy_speed_to_led_trigger(unsigned int speed) for instance, which
would be more robust to adding other speeds in the future.
> + default:
> + plt = NULL;
> + break;
> + }
> +
> + if (plt != phy->last_triggered) {
> + led_trigger_event(&phy->last_triggered->trigger, LED_OFF);
> + led_trigger_event(&plt->trigger, LED_FULL);
> + phy->last_triggered = plt;
> + }
> +}
> +EXPORT_SYMBOL_GPL(phy_led_trigger_change_speed);
> +
> +static int phy_led_trigger_register(struct phy_device *phy,
> + struct phy_led_trigger *plt, int i)
> +{
> + static const char * const name_suffix[] = {
> + "10Mb",
> + "100Mb",
> + "Gb",
> + "2.5Gb",
> + "10GbE",
Same comment as initially, the 10GbE is slightly inconsistent here wrt
the other speed encodings.
>
> @@ -402,6 +403,14 @@ struct phy_device {
>
> int link_timeout;
>
> +#ifdef CONFIG_LED_TRIGGER_PHY
> + /*
> + * A led_trigger per SPEED_*
> + */
> + struct phy_led_trigger phy_led_trigger[5];
Same comment, we would probably want to have a define/enum value for the
maximum number of speeds supported.
> +#include <linux/leds.h>
> +
> +struct phy_led_trigger {
> + struct led_trigger trigger;
> + char name[64];
Can we size this buffer based on MII_BUS_ID_SIZE, the amount of
characters needed to represent a PHY device, and the maximum trigger
name size?
> +#else
> +
> +static inline int phy_led_triggers_register(struct phy_device *phy)
> +{
> + return 0;
> +}
> +static inline void phy_led_triggers_unregister(struct phy_device *phy) { }
> +static inline void phy_led_trigger_change_speed(struct phy_device *phy) { }
Kudos for adding stubs!
--
Florian
^ permalink raw reply
* Re: [PATCHv3 net-next 08/15] nfp: add BPF to NFP code translator
From: Alexei Starovoitov @ 2016-09-14 23:15 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: netdev, ast, daniel, jiri, john.fastabend, kubakici
In-Reply-To: <1473879623-15382-9-git-send-email-jakub.kicinski@netronome.com>
On Wed, Sep 14, 2016 at 08:00:16PM +0100, Jakub Kicinski wrote:
> Add translator for JITing eBPF to operations which
> can be executed on NFP's programmable engines.
>
> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> ---
> v3:
> - don't clone the program for the verifier (no longer needed);
> - temporarily add a local copy of macros from bitfield.h.
so what's the status of that other patch? which tree is it going through?
Does it mean we'd have to wait till after the merge window? :(
That would be sad, since it looks like it almost ready.
^ permalink raw reply
* [PATCH net-next 4/4] rxrpc: Add IPv6 support [ver #2]
From: David Howells @ 2016-09-14 23:06 UTC (permalink / raw)
To: netdev; +Cc: dhowells, linux-afs, linux-kernel
In-Reply-To: <147389436004.2083.13454744739435764689.stgit@warthog.procyon.org.uk>
Add IPv6 support to AF_RXRPC. With this, AF_RXRPC sockets can be created:
service = socket(AF_RXRPC, SOCK_DGRAM, PF_INET6);
instead of:
service = socket(AF_RXRPC, SOCK_DGRAM, PF_INET);
The AFS filesystem doesn't support IPv6 at the moment, though, since that
requires upgrades to some of the RPC calls.
Note that a good portion of this patch is replacing "%pI4:%u" in print
statements with "%pISpc" which is able to handle both protocols and print
the port.
Signed-off-by: David Howells <dhowells@redhat.com>
---
net/rxrpc/Kconfig | 7 +++
net/rxrpc/af_rxrpc.c | 20 ++++++--
net/rxrpc/conn_object.c | 10 ++++
net/rxrpc/local_object.c | 37 +++++++-------
net/rxrpc/output.c | 18 +++++++
net/rxrpc/peer_event.c | 26 ++++++++++
net/rxrpc/peer_object.c | 119 ++++++++++++++++++++++++++++++----------------
net/rxrpc/proc.c | 30 +++++-------
net/rxrpc/utils.c | 2 +
9 files changed, 186 insertions(+), 83 deletions(-)
diff --git a/net/rxrpc/Kconfig b/net/rxrpc/Kconfig
index 784c53163b7b..13396c74b5c1 100644
--- a/net/rxrpc/Kconfig
+++ b/net/rxrpc/Kconfig
@@ -19,6 +19,13 @@ config AF_RXRPC
See Documentation/networking/rxrpc.txt.
+config AF_RXRPC_IPV6
+ bool "IPv6 support for RxRPC"
+ depends on (IPV6 = m && AF_RXRPC = m) || (IPV6 = y && AF_RXRPC)
+ help
+ Say Y here to allow AF_RXRPC to use IPV6 UDP as well as IPV4 UDP as
+ its network transport.
+
config AF_RXRPC_DEBUG
bool "RxRPC dynamic debugging"
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index 741b0d8d2e8c..09f81befc705 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -106,19 +106,25 @@ static int rxrpc_validate_address(struct rxrpc_sock *rx,
case AF_INET:
if (srx->transport_len < sizeof(struct sockaddr_in))
return -EINVAL;
- _debug("INET: %x @ %pI4",
- ntohs(srx->transport.sin.sin_port),
- &srx->transport.sin.sin_addr);
tail = offsetof(struct sockaddr_rxrpc, transport.sin.__pad);
break;
+#ifdef CONFIG_AF_RXRPC_IPV6
case AF_INET6:
+ if (srx->transport_len < sizeof(struct sockaddr_in6))
+ return -EINVAL;
+ tail = offsetof(struct sockaddr_rxrpc, transport) +
+ sizeof(struct sockaddr_in6);
+ break;
+#endif
+
default:
return -EAFNOSUPPORT;
}
if (tail < len)
memset((void *)srx + tail, 0, len - tail);
+ _debug("INET: %pISp", &srx->transport);
return 0;
}
@@ -409,6 +415,11 @@ static int rxrpc_sendmsg(struct socket *sock, struct msghdr *m, size_t len)
case AF_INET:
rx->srx.transport_len = sizeof(struct sockaddr_in);
break;
+#ifdef CONFIG_AF_RXRPC_IPV6
+ case AF_INET6:
+ rx->srx.transport_len = sizeof(struct sockaddr_in6);
+ break;
+#endif
default:
ret = -EAFNOSUPPORT;
goto error_unlock;
@@ -563,7 +574,8 @@ static int rxrpc_create(struct net *net, struct socket *sock, int protocol,
return -EAFNOSUPPORT;
/* we support transport protocol UDP/UDP6 only */
- if (protocol != PF_INET)
+ if (protocol != PF_INET &&
+ IS_ENABLED(CONFIG_AF_RXRPC_IPV6) && protocol != PF_INET6)
return -EPROTONOSUPPORT;
if (sock->type != SOCK_DGRAM)
diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c
index ffa9addb97b2..bb1f29280aea 100644
--- a/net/rxrpc/conn_object.c
+++ b/net/rxrpc/conn_object.c
@@ -134,6 +134,16 @@ struct rxrpc_connection *rxrpc_find_connection_rcu(struct rxrpc_local *local,
srx.transport.sin.sin_addr.s_addr)
goto not_found;
break;
+#ifdef CONFIG_AF_RXRPC_IPV6
+ case AF_INET6:
+ if (peer->srx.transport.sin6.sin6_port !=
+ srx.transport.sin6.sin6_port ||
+ memcmp(&peer->srx.transport.sin6.sin6_addr,
+ &srx.transport.sin6.sin6_addr,
+ sizeof(struct in6_addr)) != 0)
+ goto not_found;
+ break;
+#endif
default:
BUG();
}
diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
index 8720be2a6250..e3fad80b0795 100644
--- a/net/rxrpc/local_object.c
+++ b/net/rxrpc/local_object.c
@@ -58,6 +58,17 @@ static long rxrpc_local_cmp_key(const struct rxrpc_local *local,
memcmp(&local->srx.transport.sin.sin_addr,
&srx->transport.sin.sin_addr,
sizeof(struct in_addr));
+#ifdef CONFIG_AF_RXRPC_IPV6
+ case AF_INET6:
+ /* If the choice of UDP6 port is left up to the transport, then
+ * the endpoint record doesn't match.
+ */
+ return ((u16 __force)local->srx.transport.sin6.sin6_port -
+ (u16 __force)srx->transport.sin6.sin6_port) ?:
+ memcmp(&local->srx.transport.sin6.sin6_addr,
+ &srx->transport.sin6.sin6_addr,
+ sizeof(struct in6_addr));
+#endif
default:
BUG();
}
@@ -100,7 +111,8 @@ static int rxrpc_open_socket(struct rxrpc_local *local)
struct sock *sock;
int ret, opt;
- _enter("%p{%d}", local, local->srx.transport_type);
+ _enter("%p{%d,%d}",
+ local, local->srx.transport_type, local->srx.transport.family);
/* create a socket to represent the local endpoint */
ret = sock_create_kern(&init_net, local->srx.transport.family,
@@ -169,18 +181,8 @@ struct rxrpc_local *rxrpc_lookup_local(const struct sockaddr_rxrpc *srx)
long diff;
int ret;
- if (srx->transport.family == AF_INET) {
- _enter("{%d,%u,%pI4+%hu}",
- srx->transport_type,
- srx->transport.family,
- &srx->transport.sin.sin_addr,
- ntohs(srx->transport.sin.sin_port));
- } else {
- _enter("{%d,%u}",
- srx->transport_type,
- srx->transport.family);
- return ERR_PTR(-EAFNOSUPPORT);
- }
+ _enter("{%d,%d,%pISp}",
+ srx->transport_type, srx->transport.family, &srx->transport);
mutex_lock(&rxrpc_local_mutex);
@@ -233,13 +235,8 @@ struct rxrpc_local *rxrpc_lookup_local(const struct sockaddr_rxrpc *srx)
found:
mutex_unlock(&rxrpc_local_mutex);
- _net("LOCAL %s %d {%d,%u,%pI4+%hu}",
- age,
- local->debug_id,
- local->srx.transport_type,
- local->srx.transport.family,
- &local->srx.transport.sin.sin_addr,
- ntohs(local->srx.transport.sin.sin_port));
+ _net("LOCAL %s %d {%pISp}",
+ age, local->debug_id, &local->srx.transport);
_leave(" = %p", local);
return local;
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
index ec3621f2c5c8..06a9aca739d1 100644
--- a/net/rxrpc/output.c
+++ b/net/rxrpc/output.c
@@ -258,6 +258,24 @@ send_fragmentable:
(char *)&opt, sizeof(opt));
}
break;
+
+#ifdef CONFIG_AF_RXRPC_IPV6
+ case AF_INET6:
+ opt = IPV6_PMTUDISC_DONT;
+ ret = kernel_setsockopt(conn->params.local->socket,
+ SOL_IPV6, IPV6_MTU_DISCOVER,
+ (char *)&opt, sizeof(opt));
+ if (ret == 0) {
+ ret = kernel_sendmsg(conn->params.local->socket, &msg,
+ iov, 1, iov[0].iov_len);
+
+ opt = IPV6_PMTUDISC_DO;
+ kernel_setsockopt(conn->params.local->socket,
+ SOL_IPV6, IPV6_MTU_DISCOVER,
+ (char *)&opt, sizeof(opt));
+ }
+ break;
+#endif
}
up_write(&conn->params.local->defrag_sem);
diff --git a/net/rxrpc/peer_event.c b/net/rxrpc/peer_event.c
index c8948936c6fc..9e0725f5652b 100644
--- a/net/rxrpc/peer_event.c
+++ b/net/rxrpc/peer_event.c
@@ -66,6 +66,32 @@ static struct rxrpc_peer *rxrpc_lookup_peer_icmp_rcu(struct rxrpc_local *local,
}
break;
+#ifdef CONFIG_AF_RXRPC_IPV6
+ case AF_INET6:
+ srx.transport.sin6.sin6_port = serr->port;
+ srx.transport_len = sizeof(struct sockaddr_in6);
+ switch (serr->ee.ee_origin) {
+ case SO_EE_ORIGIN_ICMP6:
+ _net("Rx ICMP6");
+ memcpy(&srx.transport.sin6.sin6_addr,
+ skb_network_header(skb) + serr->addr_offset,
+ sizeof(struct in6_addr));
+ break;
+ case SO_EE_ORIGIN_ICMP:
+ _net("Rx ICMP on v6 sock");
+ memcpy(srx.transport.sin6.sin6_addr.s6_addr + 12,
+ skb_network_header(skb) + serr->addr_offset,
+ sizeof(struct in_addr));
+ break;
+ default:
+ memcpy(&srx.transport.sin6.sin6_addr,
+ &ipv6_hdr(skb)->saddr,
+ sizeof(struct in6_addr));
+ break;
+ }
+ break;
+#endif
+
default:
BUG();
}
diff --git a/net/rxrpc/peer_object.c b/net/rxrpc/peer_object.c
index 3e6cd174b53d..f3e5766910fd 100644
--- a/net/rxrpc/peer_object.c
+++ b/net/rxrpc/peer_object.c
@@ -16,12 +16,14 @@
#include <linux/skbuff.h>
#include <linux/udp.h>
#include <linux/in.h>
+#include <linux/in6.h>
#include <linux/slab.h>
#include <linux/hashtable.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include <net/ip.h>
#include <net/route.h>
+#include <net/ip6_route.h>
#include "ar-internal.h"
static DEFINE_HASHTABLE(rxrpc_peer_hash, 10);
@@ -50,6 +52,13 @@ static unsigned long rxrpc_peer_hash_key(struct rxrpc_local *local,
size = sizeof(srx->transport.sin.sin_addr);
p = (u16 *)&srx->transport.sin.sin_addr;
break;
+#ifdef CONFIG_AF_RXRPC_IPV6
+ case AF_INET6:
+ hash_key += (u16 __force)srx->transport.sin.sin_port;
+ size = sizeof(srx->transport.sin6.sin6_addr);
+ p = (u16 *)&srx->transport.sin6.sin6_addr;
+ break;
+#endif
default:
WARN(1, "AF_RXRPC: Unsupported transport address family\n");
return 0;
@@ -93,6 +102,14 @@ static long rxrpc_peer_cmp_key(const struct rxrpc_peer *peer,
memcmp(&peer->srx.transport.sin.sin_addr,
&srx->transport.sin.sin_addr,
sizeof(struct in_addr));
+#ifdef CONFIG_AF_RXRPC_IPV6
+ case AF_INET6:
+ return ((u16 __force)peer->srx.transport.sin6.sin6_port -
+ (u16 __force)srx->transport.sin6.sin6_port) ?:
+ memcmp(&peer->srx.transport.sin6.sin6_addr,
+ &srx->transport.sin6.sin6_addr,
+ sizeof(struct in6_addr));
+#endif
default:
BUG();
}
@@ -130,17 +147,7 @@ struct rxrpc_peer *rxrpc_lookup_peer_rcu(struct rxrpc_local *local,
peer = __rxrpc_lookup_peer_rcu(local, srx, hash_key);
if (peer) {
- switch (srx->transport.family) {
- case AF_INET:
- _net("PEER %d {%d,%u,%pI4+%hu}",
- peer->debug_id,
- peer->srx.transport_type,
- peer->srx.transport.family,
- &peer->srx.transport.sin.sin_addr,
- ntohs(peer->srx.transport.sin.sin_port));
- break;
- }
-
+ _net("PEER %d {%pISp}", peer->debug_id, &peer->srx.transport);
_leave(" = %p {u=%d}", peer, atomic_read(&peer->usage));
}
return peer;
@@ -152,22 +159,53 @@ struct rxrpc_peer *rxrpc_lookup_peer_rcu(struct rxrpc_local *local,
*/
static void rxrpc_assess_MTU_size(struct rxrpc_peer *peer)
{
+ struct dst_entry *dst;
struct rtable *rt;
- struct flowi4 fl4;
+ struct flowi fl;
+ struct flowi4 *fl4 = &fl.u.ip4;
+#ifdef CONFIG_AF_RXRPC_IPV6
+ struct flowi6 *fl6 = &fl.u.ip6;
+#endif
peer->if_mtu = 1500;
- rt = ip_route_output_ports(&init_net, &fl4, NULL,
- peer->srx.transport.sin.sin_addr.s_addr, 0,
- htons(7000), htons(7001),
- IPPROTO_UDP, 0, 0);
- if (IS_ERR(rt)) {
- _leave(" [route err %ld]", PTR_ERR(rt));
- return;
+ memset(&fl, 0, sizeof(fl));
+ switch (peer->srx.transport.family) {
+ case AF_INET:
+ rt = ip_route_output_ports(
+ &init_net, fl4, NULL,
+ peer->srx.transport.sin.sin_addr.s_addr, 0,
+ htons(7000), htons(7001), IPPROTO_UDP, 0, 0);
+ if (IS_ERR(rt)) {
+ _leave(" [route err %ld]", PTR_ERR(rt));
+ return;
+ }
+ dst = &rt->dst;
+ break;
+
+#ifdef CONFIG_AF_RXRPC_IPV6
+ case AF_INET6:
+ fl6->flowi6_iif = LOOPBACK_IFINDEX;
+ fl6->flowi6_scope = RT_SCOPE_UNIVERSE;
+ fl6->flowi6_proto = IPPROTO_UDP;
+ memcpy(&fl6->daddr, &peer->srx.transport.sin6.sin6_addr,
+ sizeof(struct in6_addr));
+ fl6->fl6_dport = htons(7001);
+ fl6->fl6_sport = htons(7000);
+ dst = ip6_route_output(&init_net, NULL, fl6);
+ if (IS_ERR(dst)) {
+ _leave(" [route err %ld]", PTR_ERR(dst));
+ return;
+ }
+ break;
+#endif
+
+ default:
+ BUG();
}
- peer->if_mtu = dst_mtu(&rt->dst);
- dst_release(&rt->dst);
+ peer->if_mtu = dst_mtu(dst);
+ dst_release(dst);
_leave(" [if_mtu %u]", peer->if_mtu);
}
@@ -207,17 +245,24 @@ static void rxrpc_init_peer(struct rxrpc_peer *peer, unsigned long hash_key)
rxrpc_assess_MTU_size(peer);
peer->mtu = peer->if_mtu;
- if (peer->srx.transport.family == AF_INET) {
+ switch (peer->srx.transport.family) {
+ case AF_INET:
peer->hdrsize = sizeof(struct iphdr);
- switch (peer->srx.transport_type) {
- case SOCK_DGRAM:
- peer->hdrsize += sizeof(struct udphdr);
- break;
- default:
- BUG();
- break;
- }
- } else {
+ break;
+#ifdef CONFIG_AF_RXRPC_IPV6
+ case AF_INET6:
+ peer->hdrsize = sizeof(struct ipv6hdr);
+ break;
+#endif
+ default:
+ BUG();
+ }
+
+ switch (peer->srx.transport_type) {
+ case SOCK_DGRAM:
+ peer->hdrsize += sizeof(struct udphdr);
+ break;
+ default:
BUG();
}
@@ -285,11 +330,7 @@ struct rxrpc_peer *rxrpc_lookup_peer(struct rxrpc_local *local,
struct rxrpc_peer *peer, *candidate;
unsigned long hash_key = rxrpc_peer_hash_key(local, srx);
- _enter("{%d,%d,%pI4+%hu}",
- srx->transport_type,
- srx->transport_len,
- &srx->transport.sin.sin_addr,
- ntohs(srx->transport.sin.sin_port));
+ _enter("{%pISp}", &srx->transport);
/* search the peer list first */
rcu_read_lock();
@@ -326,11 +367,7 @@ struct rxrpc_peer *rxrpc_lookup_peer(struct rxrpc_local *local,
peer = candidate;
}
- _net("PEER %d {%d,%pI4+%hu}",
- peer->debug_id,
- peer->srx.transport_type,
- &peer->srx.transport.sin.sin_addr,
- ntohs(peer->srx.transport.sin.sin_port));
+ _net("PEER %d {%pISp}", peer->debug_id, &peer->srx.transport);
_leave(" = %p {u=%d}", peer, atomic_read(&peer->usage));
return peer;
diff --git a/net/rxrpc/proc.c b/net/rxrpc/proc.c
index d529d1b4021c..65cd980767fa 100644
--- a/net/rxrpc/proc.c
+++ b/net/rxrpc/proc.c
@@ -52,11 +52,12 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
struct rxrpc_sock *rx;
struct rxrpc_peer *peer;
struct rxrpc_call *call;
- char lbuff[4 + 4 + 4 + 4 + 5 + 1], rbuff[4 + 4 + 4 + 4 + 5 + 1];
+ char lbuff[50], rbuff[50];
if (v == &rxrpc_calls) {
seq_puts(seq,
- "Proto Local Remote "
+ "Proto Local "
+ " Remote "
" SvID ConnID CallID End Use State Abort "
" UserID\n");
return 0;
@@ -68,9 +69,7 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
if (rx) {
local = READ_ONCE(rx->local);
if (local)
- sprintf(lbuff, "%pI4:%u",
- &local->srx.transport.sin.sin_addr,
- ntohs(local->srx.transport.sin.sin_port));
+ sprintf(lbuff, "%pISpc", &local->srx.transport);
else
strcpy(lbuff, "no_local");
} else {
@@ -79,14 +78,12 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
peer = call->peer;
if (peer)
- sprintf(rbuff, "%pI4:%u",
- &peer->srx.transport.sin.sin_addr,
- ntohs(peer->srx.transport.sin.sin_port));
+ sprintf(rbuff, "%pISpc", &peer->srx.transport);
else
strcpy(rbuff, "no_connection");
seq_printf(seq,
- "UDP %-22.22s %-22.22s %4x %08x %08x %s %3u"
+ "UDP %-47.47s %-47.47s %4x %08x %08x %s %3u"
" %-8.8s %08x %lx\n",
lbuff,
rbuff,
@@ -145,11 +142,12 @@ static void rxrpc_connection_seq_stop(struct seq_file *seq, void *v)
static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)
{
struct rxrpc_connection *conn;
- char lbuff[4 + 4 + 4 + 4 + 5 + 1], rbuff[4 + 4 + 4 + 4 + 5 + 1];
+ char lbuff[50], rbuff[50];
if (v == &rxrpc_connection_proc_list) {
seq_puts(seq,
- "Proto Local Remote "
+ "Proto Local "
+ " Remote "
" SvID ConnID End Use State Key "
" Serial ISerial\n"
);
@@ -163,16 +161,12 @@ static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)
goto print;
}
- sprintf(lbuff, "%pI4:%u",
- &conn->params.local->srx.transport.sin.sin_addr,
- ntohs(conn->params.local->srx.transport.sin.sin_port));
+ sprintf(lbuff, "%pISpc", &conn->params.local->srx.transport);
- sprintf(rbuff, "%pI4:%u",
- &conn->params.peer->srx.transport.sin.sin_addr,
- ntohs(conn->params.peer->srx.transport.sin.sin_port));
+ sprintf(rbuff, "%pISpc", &conn->params.peer->srx.transport);
print:
seq_printf(seq,
- "UDP %-22.22s %-22.22s %4x %08x %s %3u"
+ "UDP %-47.47s %-47.47s %4x %08x %s %3u"
" %s %08x %08x %08x\n",
lbuff,
rbuff,
diff --git a/net/rxrpc/utils.c b/net/rxrpc/utils.c
index b88914d53ca5..ff7af71c4b49 100644
--- a/net/rxrpc/utils.c
+++ b/net/rxrpc/utils.c
@@ -30,6 +30,7 @@ int rxrpc_extract_addr_from_skb(struct sockaddr_rxrpc *srx, struct sk_buff *skb)
srx->transport.sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
return 0;
+#ifdef CONFIG_AF_RXRPC_IPV6
case ETH_P_IPV6:
srx->transport_type = SOCK_DGRAM;
srx->transport_len = sizeof(srx->transport.sin6);
@@ -37,6 +38,7 @@ int rxrpc_extract_addr_from_skb(struct sockaddr_rxrpc *srx, struct sk_buff *skb)
srx->transport.sin6.sin6_port = udp_hdr(skb)->source;
srx->transport.sin6.sin6_addr = ipv6_hdr(skb)->saddr;
return 0;
+#endif
default:
pr_warn_ratelimited("AF_RXRPC: Unknown eth protocol %u\n",
^ permalink raw reply related
* [PATCH net-next 3/4] rxrpc: Use rxrpc_extract_addr_from_skb() rather than doing this manually [ver #2]
From: David Howells @ 2016-09-14 23:06 UTC (permalink / raw)
To: netdev; +Cc: dhowells, linux-afs, linux-kernel
In-Reply-To: <147389436004.2083.13454744739435764689.stgit@warthog.procyon.org.uk>
There are two places that want to transmit a packet in response to one just
received and manually pick the address to reply to out of the sk_buff.
Make them use rxrpc_extract_addr_from_skb() instead so that IPv6 is handled
automatically.
Signed-off-by: David Howells <dhowells@redhat.com>
---
net/rxrpc/local_event.c | 13 +++++--------
net/rxrpc/output.c | 32 ++++++--------------------------
2 files changed, 11 insertions(+), 34 deletions(-)
diff --git a/net/rxrpc/local_event.c b/net/rxrpc/local_event.c
index cdd58e6e9fbd..f073e932500e 100644
--- a/net/rxrpc/local_event.c
+++ b/net/rxrpc/local_event.c
@@ -15,8 +15,6 @@
#include <linux/net.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
-#include <linux/udp.h>
-#include <linux/ip.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include <generated/utsrelease.h>
@@ -33,7 +31,7 @@ static void rxrpc_send_version_request(struct rxrpc_local *local,
{
struct rxrpc_wire_header whdr;
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
- struct sockaddr_in sin;
+ struct sockaddr_rxrpc srx;
struct msghdr msg;
struct kvec iov[2];
size_t len;
@@ -41,12 +39,11 @@ static void rxrpc_send_version_request(struct rxrpc_local *local,
_enter("");
- sin.sin_family = AF_INET;
- sin.sin_port = udp_hdr(skb)->source;
- sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
+ if (rxrpc_extract_addr_from_skb(&srx, skb) < 0)
+ return;
- msg.msg_name = &sin;
- msg.msg_namelen = sizeof(sin);
+ msg.msg_name = &srx.transport;
+ msg.msg_namelen = srx.transport_len;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
index 90c7722d5779..ec3621f2c5c8 100644
--- a/net/rxrpc/output.c
+++ b/net/rxrpc/output.c
@@ -15,8 +15,6 @@
#include <linux/gfp.h>
#include <linux/skbuff.h>
#include <linux/export.h>
-#include <linux/udp.h>
-#include <linux/ip.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include "ar-internal.h"
@@ -272,10 +270,7 @@ send_fragmentable:
*/
void rxrpc_reject_packets(struct rxrpc_local *local)
{
- union {
- struct sockaddr sa;
- struct sockaddr_in sin;
- } sa;
+ struct sockaddr_rxrpc srx;
struct rxrpc_skb_priv *sp;
struct rxrpc_wire_header whdr;
struct sk_buff *skb;
@@ -292,32 +287,21 @@ void rxrpc_reject_packets(struct rxrpc_local *local)
iov[1].iov_len = sizeof(code);
size = sizeof(whdr) + sizeof(code);
- msg.msg_name = &sa;
+ msg.msg_name = &srx.transport;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
- memset(&sa, 0, sizeof(sa));
- sa.sa.sa_family = local->srx.transport.family;
- switch (sa.sa.sa_family) {
- case AF_INET:
- msg.msg_namelen = sizeof(sa.sin);
- break;
- default:
- msg.msg_namelen = 0;
- break;
- }
-
memset(&whdr, 0, sizeof(whdr));
whdr.type = RXRPC_PACKET_TYPE_ABORT;
while ((skb = skb_dequeue(&local->reject_queue))) {
rxrpc_see_skb(skb);
sp = rxrpc_skb(skb);
- switch (sa.sa.sa_family) {
- case AF_INET:
- sa.sin.sin_port = udp_hdr(skb)->source;
- sa.sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
+
+ if (rxrpc_extract_addr_from_skb(&srx, skb) == 0) {
+ msg.msg_namelen = srx.transport_len;
+
code = htonl(skb->priority);
whdr.epoch = htonl(sp->hdr.epoch);
@@ -329,10 +313,6 @@ void rxrpc_reject_packets(struct rxrpc_local *local)
whdr.flags &= RXRPC_CLIENT_INITIATED;
kernel_sendmsg(local->socket, &msg, iov, 2, size);
- break;
-
- default:
- break;
}
rxrpc_free_skb(skb);
^ permalink raw reply related
* [PATCH net-next 2/4] rxrpc: Don't specify protocol to when creating transport socket [ver #2]
From: David Howells @ 2016-09-14 23:06 UTC (permalink / raw)
To: netdev; +Cc: dhowells, linux-afs, linux-kernel
In-Reply-To: <147389436004.2083.13454744739435764689.stgit@warthog.procyon.org.uk>
Pass 0 as the protocol argument when creating the transport socket rather
than IPPROTO_UDP.
Signed-off-by: David Howells <dhowells@redhat.com>
---
net/rxrpc/local_object.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
index 782b9adf67cb..8720be2a6250 100644
--- a/net/rxrpc/local_object.c
+++ b/net/rxrpc/local_object.c
@@ -103,8 +103,8 @@ static int rxrpc_open_socket(struct rxrpc_local *local)
_enter("%p{%d}", local, local->srx.transport_type);
/* create a socket to represent the local endpoint */
- ret = sock_create_kern(&init_net, PF_INET, local->srx.transport_type,
- IPPROTO_UDP, &local->socket);
+ ret = sock_create_kern(&init_net, local->srx.transport.family,
+ local->srx.transport_type, 0, &local->socket);
if (ret < 0) {
_leave(" = %d [socket]", ret);
return ret;
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox