Skip to content

Commit

Permalink
ping: Refactor socket mark failure handling
Browse files Browse the repository at this point in the history
Ping warned 2x about setsockopt SO_MARK failure, because since 08f0e17
is called also for probe socket (before it was only on real socket):

    $ ping -m 2 ::1
    ping: WARNING: failed to set mark: 2: Operation not permitted
    PING ::1 (::1) 56 data bytes
    ping: WARNING: failed to set mark: 2: Operation not permitted
    64 bytes from ::1: icmp_seq=1 ttl=64 time=0.039 ms

Therefore pass rts struct to:
1) Disable SO_MARK call on real socket when it failed on probe socket,
therefore only single warning is printed.
2) Print hint about possible missing cap_net_admin+p capability

    $ ./builddir/ping/ping -m 2 ::1
    ./builddir/ping/ping: WARNING: failed to set mark: 2: Operation not permitted
    ./builddir/ping/ping: => missing cap_net_admin+p capability?
    PING ::1 (::1) 56 data bytes
    64 bytes from ::1: icmp_seq=1 ttl=64 time=0.053 ms

Fixes: 08f0e17 ("ping: Set mark (SO_MARK) on probe socket")
Fixes: iputils#515
Reviewed-by: Matthias Gerstner <matthias.gerstner@suse.com>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
  • Loading branch information
pevik committed Jan 16, 2024
1 parent 4470e7d commit 7300b01
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 12 deletions.
3 changes: 1 addition & 2 deletions ping/ping.c
Original file line number Diff line number Diff line change
Expand Up @@ -828,8 +828,7 @@ int ping4_run(struct ping_rts *rts, int argc, char **argv, struct addrinfo *ai,
setsockopt(probe_fd, IPPROTO_IP, IP_TOS, (char *)&rts->settos, sizeof(int)) < 0)
error(0, errno, _("warning: QOS sockopts"));

if (rts->opt_mark)
sock_setmark(rts->mark, probe_fd);
sock_setmark(rts, probe_fd);

dst.sin_port = htons(1025);
if (rts->nroute)
Expand Down
2 changes: 1 addition & 1 deletion ping/ping.h
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ char *str_interval(int interval);
int is_ours(struct ping_rts *rts, socket_st *sock, uint16_t id);
extern int pinger(struct ping_rts *rts, ping_func_set_st *fset, socket_st *sock);
extern void sock_setbufs(struct ping_rts *rts, socket_st *, int alloc);
extern void sock_setmark(unsigned int mark, int fd);
extern void sock_setmark(struct ping_rts *rts, int fd);
extern void setup(struct ping_rts *rts, socket_st *);
extern int main_loop(struct ping_rts *rts, ping_func_set_st *fset, socket_st*,
uint8_t *packet, int packlen);
Expand Down
3 changes: 1 addition & 2 deletions ping/ping6_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,7 @@ int ping6_run(struct ping_rts *rts, int argc, char **argv, struct addrinfo *ai,
!IN6_IS_ADDR_MC_LINKLOCAL(&rts->firsthop.sin6_addr))
rts->firsthop.sin6_family = AF_INET6;

if (rts->opt_mark)
sock_setmark(rts->mark, probe_fd);
sock_setmark(rts, probe_fd);

rts->firsthop.sin6_port = htons(1025);
if (connect(probe_fd, (struct sockaddr *)&rts->firsthop, sizeof(rts->firsthop)) == -1) {
Expand Down
19 changes: 12 additions & 7 deletions ping/ping_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,20 +455,26 @@ void sock_setbufs(struct ping_rts *rts, socket_st *sock, int alloc)
}
}

void sock_setmark(unsigned int mark, int fd)
void sock_setmark(struct ping_rts *rts, int fd)
{
#ifdef SO_MARK
int ret;
int errno_save;

if (!rts->opt_mark)
return;

enable_capability_admin();
ret = setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark));
ret = setsockopt(fd, SOL_SOCKET, SO_MARK, &(rts->mark), sizeof(rts->mark));
errno_save = errno;
disable_capability_admin();

/* Do not exit, old kernels do not support mark. */
if (ret == -1)
error(0, errno_save, _("WARNING: failed to set mark: %u"), mark);
if (ret == -1) {
error(0, errno_save, _("WARNING: failed to set mark: %u"), rts->mark);
if (errno_save == EPERM)
error(0, 0, _("=> missing cap_net_admin+p capability?"));
rts->opt_mark = 0;
}
#else
error(0, errno_save, _("WARNING: SO_MARK not supported"));
#endif
Expand Down Expand Up @@ -506,8 +512,7 @@ void setup(struct ping_rts *rts, socket_st *sock)
}
#endif

if (rts->opt_mark)
sock_setmark(rts->mark, sock->fd);
sock_setmark(rts, sock->fd);

/* Set some SNDTIMEO to prevent blocking forever
* on sends, when device is too slow or stalls. Just put limit
Expand Down

0 comments on commit 7300b01

Please sign in to comment.